home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Tools / freeWAIS-sf-1.1 / ir / ircfiles.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-19  |  94.3 KB  |  3,945 lines

  1. /* WIDE AREA INFORMATION SERVER SOFTWARE:
  2.    No guarantees or restrictions.  See the readme file for the full standard
  3.    disclaimer.
  4.  
  5.    Brewster@think.com
  6. */
  7.  
  8. /* Copyright (c) CNIDR (see ../COPYRIGHT) */
  9.  
  10.  
  11. /* this file defines a set of helper functions
  12.  * for indexing common types of files.
  13.  * -brewster 7/90
  14.  */
  15.  
  16. /* I encourage adding customizations.
  17.  * (too bad they all have to be hard coded, but
  18.  *  C did not have convenient dynamic linking facilities)
  19.  *
  20.  * Add three functions to this file:
  21.  * boolean foo_separator_function(char *line){}
  22.  * void foo_header_function(char *line){}
  23.  * long foo_date_function(char *line){}
  24.  * void foo_finish_header_function(char *header){}
  25.  *
  26.  * then add the prototypes to ircfiles.h
  27.  * then add the functions to the big case statement in irbuild.c
  28.  *
  29.  *
  30.  * to do:
  31.  *   filter for digests
  32.  *
  33.  *   Tracy pointed out 2 things which we should consider when redesigning the
  34.  *   parser:
  35.  *
  36.  *   - there should be a way for the parser to decide to skip a section of 
  37.  *   input text (ie. not index it).  she does this by having global variable 
  38.  *   which is set by her custom seperator function when it wants to tell 
  39.  *   map_over_words() to not add the words on the current line
  40.  *
  41.  *   - there should be a way to switch lexers depending what section of a
  42.  *   document you are in (since word separators will change).  This is 
  43.  *   needed by the european patent office too.
  44.  *
  45.  */
  46.  
  47.  
  48. /* Change log:
  49.  * 8/90 brewster added the library customizations
  50.  * 6/91 and before - added a bunch of other filters - JG
  51.  * $Log: ircfiles.c,v $
  52.  * Revision 1.12  1994/12/19  16:53:59  pfeifer
  53.  * Michael Schmidt one-off bug with date
  54.  *
  55.  * Revision 1.11  1994/08/23  12:32:00  pfeifer
  56.  * Moved HEADLINE constants to Defaults.tmpl
  57.  *
  58.  * Revision 1.10  1994/06/03  11:42:56  huynh1
  59.  * bug in headlines specification corrected.
  60.  *
  61.  * Revision 1.9  1994/05/19  12:53:11  huynh1
  62.  * fields_header_function updated.
  63.  *
  64.  * Revision 1.8  1994/03/28  09:29:21  pfeifer
  65.  * Integrated Essence
  66.  *
  67.  * Revision 1.7  1994/03/23  13:05:46  pfeifer
  68.  * removed the include iso.h
  69.  *
  70.  * Revision 1.6  1994/03/11  15:16:54  huynh1
  71.  * bug fix corrected.
  72.  * Patchlevel 05.
  73.  *
  74.  * Revision 1.5  1994/03/08  20:38:58  pfeifer
  75.  * Patchlevel 04
  76.  *
  77.  * Revision 1.4  1994/02/14  10:28:38  huynh1
  78.  * layout_length added.
  79.  *
  80.  * Revision 1.3  93/07/21  18:45:34  warnock
  81.  * Added new functions to handle listserv logs and STELAR-specific types
  82.  * 
  83.  * Revision 1.2  93/07/19  16:31:50  warnock
  84.  * Added document type URL from Nathan.Torkington@vuw.ac.nz
  85.  * 
  86.  * Revision 1.1  1993/02/16  15:05:35  freewais
  87.  * Initial revision
  88.  *
  89.  * Revision 1.34  92/05/06  17:28:23  jonathan
  90.  * Added filename_finish_header_function.  Puts leaf name into header.
  91.  * 
  92.  * Revision 1.33  92/05/05  11:10:50  jonathan
  93.  * Added fix to bibtex indexer to ignore subsequent "booktitles" after title
  94.  * has been set.  Thanks to Lutz Prechelt (prechelt@ira.uka.de).
  95.  * 
  96.  * Revision 1.32  92/04/30  12:31:08  jonathan
  97.  * Fixed syntax errors in OBJ C functions.
  98.  * 
  99.  * Revision 1.31  92/04/29  14:08:57  shen
  100.  * chnage catalaog header string to "Title:"
  101.  * 
  102.  * Revision 1.30  92/04/26  14:45:08  brewster
  103.  * debug ziff
  104.  * 
  105.  * Revision 1.29  92/04/26  14:39:24  brewster
  106.  * tweeked ziff filter
  107.  * 
  108.  * Revision 1.28  92/04/25  21:14:05  brewster
  109.  * added ziff
  110.  * 
  111.  * Revision 1.27  92/04/20  15:21:06  morris
  112.  * added todo's for tracy
  113.  * 
  114.  * Revision 1.26  92/03/22  18:38:29  brewster
  115.  * added objective C filter
  116.  * 
  117.  * Revision 1.25  92/03/13  08:21:37  jonathan
  118.  * Added length limits to scanf's in my_getdate, thanks to
  119.  * sendall@dxpt01.cern.ch (Mike Sendall).
  120.  * 
  121.  * Revision 1.24  92/02/29  20:13:54  jonathan
  122.  * separated =- for some compilers that get confused (ULTRIX).
  123.  * 
  124.  * Revision 1.23  92/02/20  09:50:14  jonathan
  125.  * Added bibtex and nhyp filters from S.P.vandeBurgt@research.ptt.nl.
  126.  * 
  127.  * Revision 1.22  92/02/12  13:11:25  jonathan
  128.  * Changed library catalog functions for new format (from fad).
  129.  * 
  130.  * 
  131.  *
  132.  */
  133.  
  134. #include <string.h>
  135. #include <ctype.h>
  136. #include "cutil.h"
  137. #include "ircfiles.h"
  138.  
  139. #ifdef FIELDS /* tung, 1/94 */
  140. #include "field_index.h"
  141. #endif
  142. extern char *current_filename;
  143. extern int current_filecount;
  144.  
  145.  
  146. static char *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
  147.             "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL};
  148.  
  149.  
  150. static char* trim_trailing_newline _AP((char* string));
  151. static char* trim_leading_blanks _AP((char* string));
  152.  
  153. static char*
  154. trim_trailing_newline(string)
  155. char* string;
  156. {
  157.   if(string)
  158.     if(strlen(string) > 0)
  159.       if(string[strlen(string) -1] == '\n')
  160.     string[strlen(string) -1] = '\0';
  161.   return(string);
  162. }
  163.  
  164. static char*
  165. trim_leading_blanks(string)
  166. char* string;
  167. {
  168.   if(string)
  169.     if(strlen(string) > 0)
  170.       while(string[0] <= ' ')
  171.     string++;
  172.   return(string);
  173. }
  174.  
  175.  
  176. #ifdef BIO
  177.  
  178. char bio_header1[MAX_HEADER_LEN + 1];
  179. char bio_header2[MAX_HEADER_LEN + 1];
  180.  
  181.  
  182. /* ==========================================
  183.  *
  184.  * ===  Genbank Flat-file Customizations  ===
  185.  *
  186.  * d.g.gilbert, 15feb92, 
  187.  * gilbertd@bio.indiana.edu
  188.  *
  189.  * ==========================================
  190.  */
  191.  
  192. #define genbank_data_tab    12
  193. #define genbank_date_tab    63
  194.  
  195. /* Genbank Flat-file format:
  196. LOCUS       ACAAC01      1571 bp ds-DNA             INV       05-NOV-1991 << start entry
  197. 12345678901234567890123456789012345678901234567890123456789012345678901234567890
  198. .........1.........2.........3.........4.........5.........6.........7.........8
  199. all data starts at tab=13
  200. on locus line, data starts at tab=63
  201. ...
  202. LOCUS       blah    << Start entry, index LOCUS_NAME, includes DATE
  203. DEFINITION  blah       << Index def line == HEADER line
  204. ACCESSION   blah    << Index acc line
  205. KEYWORDS    blah    << index keywords
  206. SOURCE      blah    << index source
  207.   ORGANISM  blah    << index organism
  208.             blah    << index taxonomy
  209.             blah    << "
  210.   AUTHORS   blah    << Index
  211.   TITLE     blah    << Index
  212.             blah    << Index
  213. ANYOTHERS    jazz    << skipit
  214. //                  << end of entry == entry separator
  215. LOCUS       ACAAC01      1571 bp ds-DNA             INV       05-NOV-1991 << start entry
  216. DEFINITION  Acanthamoeba castelani gene encoding actin I.
  217. ACCESSION   V00002 J01016
  218. KEYWORDS    actin.
  219. SOURCE      Acanthamoeba castellanii DNA.
  220.   ORGANISM  Acanthamoeba castellanii
  221.             Eukaryota; Animalia; Protozoa; Sarcomastigophora; Sarcodina;
  222.             Rhizopoda; Lobosa; Gymnamoeba; Amoebida; Acanthopodina;
  223.             Acanthamoebidae.
  224. REFERENCE   1  (bases 1 to 1571)
  225.   AUTHORS   Nellen,W. and Gallwitz,D.
  226.   TITLE     Actin genes and actin messenger RNA in Acanthamoeba castellani.
  227.             Nucleotide sequence of the split actin gene I
  228.   JOURNAL   J. Mol. Biol. 159, 1-18 (1982)
  229. COMMENT     SWISS-PROT; P02578; ACT1$ACACA.
  230.                From EMBL 26   entry ACAC01;  dated 22-JAN-1991.
  231.  
  232. FEATURES             Location/Qualifiers
  233.     >>> ignore all features
  234.     
  235. BASE COUNT      313 a    535 c    389 g    334 t
  236. ORIGIN
  237.         1 ggagaagcgt gcacgcaata accaagcgac agagcaacct ctctggcacc acgccccaca
  238.     >>> ignore all seq data in indexing
  239. //  <<< end of entry
  240. LOCUS       ACAMHCA      5894 bp ds-DNA             INV       30-SEP-1988
  241. ...
  242. *****/
  243.  
  244.  
  245. static  boolean  keepindexing = false;
  246.  
  247. void genbank_filter_for_index(line)
  248. char* line;
  249. {
  250.   /* check whether to index anything in line, 
  251.    * call this from genbank_header_function which is called for
  252.    * each line.  
  253.    * Blank out parts of line not for indexing...
  254.    */
  255.   char *c;
  256.   long  i;
  257.   
  258.   if (strlen(line) <= genbank_data_tab) {
  259.      for (c=line ; *c>=' '; c++) *c=' ';
  260.      keepindexing= false;  
  261.        }
  262.      
  263.   else if (substrcmp(line, "            ")) {  
  264.         /* most lines are like this, including nucleotides */
  265.        if (!keepindexing) for (c=line ; *c>=' '; c++) *c=' ';
  266.      }
  267.      
  268.   /*******
  269.    else if (substrcmp(line, "LOCUS       ")){
  270.         // I think this is bad, locus not in index ... 
  271.      for (c=line, i=0; *c>=' ' && i<genbank_data_tab; i++, c++) *c=' ';
  272.      for ( ; *c>' '; c++) ;  // leave LOCUS ID intact  
  273.      for ( ; *c>=' '; c++) *c=' '; 
  274.      keepindexing= false;
  275.      }
  276.     ******/ 
  277.     
  278.   else if ( 
  279.           substrcmp(line, "DEFINITION  ") 
  280.       || substrcmp(line, "LOCUS       ")
  281.       || substrcmp(line, "ACCESSION   ")
  282.       || substrcmp(line, "KEYWORDS    ")
  283.       || substrcmp(line, "SOURCE      ")
  284.       || substrcmp(line, "  ORGANISM  ")
  285.       || substrcmp(line, "  AUTHORS   ")
  286.       || substrcmp(line, "  TITLE     ")
  287.     ){
  288.      for (c=line, i=0; *c>=' ' && i<genbank_data_tab; i++, c++) *c=' ';
  289.      keepindexing= true;
  290.      }
  291.  
  292.   else {
  293.      for (c=line ; *c>=' '; c++) *c=' ';
  294.      keepindexing= false;
  295.      }
  296. }
  297.  
  298.  
  299.  
  300. boolean genbank_separator_function(line)
  301. char *line;
  302. {
  303. /* !! with // as separator, we get // at top of entry which will
  304.    screw up seqanal software... */
  305. /*  if ((strlen(line) > 1) && (0==strncmp(line, "//", 2))){
  306.      return(true);
  307.      }  
  308. */
  309.   if ((strlen(line) > genbank_data_tab) && substrcmp(line, "LOCUS       ")){
  310.      return(true);
  311.      }
  312.   else{
  313.     return(false);
  314.     }
  315. }
  316.  
  317. long genbank_getdate(line)
  318. char *line;
  319. {
  320.     /* genbank date == 30-SEP-1988*/
  321.   char date[255], *temp;
  322.   int day, month, year;
  323.   char cmonth[25];
  324.  
  325.   strcpy(date, line);
  326.  
  327.   temp = date;
  328.  
  329.   while(!isdigit(*temp)) temp++;
  330.  
  331.   /* sscanf(temp, "%d %s %d", &day, cmonth, &year); */
  332.   sscanf(temp, "%d-%s-%d", &day, cmonth, &year);
  333.  
  334.   for(month = 0; months[month] != NULL; month++)
  335.     /* if(!strcmp(cmonth, months[month])) break; */
  336.     if(!strcasecmp(cmonth, months[month])) break; /* was stricmp !! */
  337.  
  338.   if (year > 99) year = year % 100;
  339.  
  340.   if(day > 0 && 
  341.      month < 12 &&
  342.      year > 0) {
  343.     return (10000 * year + 100 * (month+1) + day);
  344.   }
  345.   return 0;
  346. }
  347.  
  348. long genbank_date_function(line)
  349. char *line;
  350. {
  351.   if ((strlen(line) > genbank_data_tab) && substrcmp(line, "LOCUS       ")){
  352.     return(genbank_getdate(line+genbank_date_tab));
  353.   }
  354.   else 
  355.     return -1;
  356. }
  357.  
  358.   
  359.  
  360. char *genbank_def = bio_header1;
  361. char *genbank_accession= bio_header2;
  362.  
  363. void genbank_header_function(line)
  364. char *line;
  365. {
  366.   if ((strlen(line) > genbank_data_tab) && substrcmp(line, "DEFINITION  ") &&
  367.      (strlen(genbank_def) == 0)){
  368.     strncpy(genbank_def, line + genbank_data_tab, MAX_HEADER_LEN);
  369.     trim_trailing_newline(genbank_def);
  370.     }
  371.     
  372.   else if ((strlen(line) > genbank_data_tab) &&
  373.      substrcmp(line, "ACCESSION   ") &&
  374.      (strlen(genbank_accession) == 0)){
  375.     /* cut extra acc. numbers from this -- we want only 1st */
  376.     char *cp;
  377.     for (cp=line+genbank_data_tab; *cp==' '; cp++) ;
  378.     strncpy(genbank_accession, cp, MAX_HEADER_LEN);
  379.     cp= strchr(genbank_accession, ' ');
  380.     if (cp!=NULL) *cp=0; /* drop after 1st */
  381.     trim_trailing_newline(genbank_accession);
  382.     }
  383.   
  384.   genbank_filter_for_index( line);
  385.   
  386. }
  387.  
  388. void genbank_finish_header_function(header)
  389. char *header;
  390. {
  391.   if(strlen(genbank_def) != 0 && strlen(genbank_accession) != 0){
  392.     strncpy(header, genbank_accession, MAX_HEADER_LEN);
  393.     s_strncat(header, " ", MAX_HEADER_LEN, MAX_HEADER_LEN);
  394.     s_strncat(header, genbank_def, MAX_HEADER_LEN, MAX_HEADER_LEN);
  395.   }
  396.   else if(strlen(genbank_def) != 0){
  397.     strncpy(header, genbank_def, MAX_HEADER_LEN);
  398.   }
  399.   else if(strlen(genbank_accession) != 0){
  400.     strncpy(header, genbank_accession, MAX_HEADER_LEN);
  401.   }
  402.   else{
  403.     strcpy(header, "Unknown Entry");
  404.   }
  405.   genbank_def[0] = '\0';
  406.   genbank_accession[0] = '\0';
  407. }
  408.  
  409.  
  410. /* ==========================================
  411.  *
  412.  * ===  PIR Protein Customizations  ===
  413.  *
  414.  * d.g.gilbert, 11Mar92, 
  415.  * gilbertd@bio.indiana.edu
  416.  *
  417.  * ==========================================
  418.  */
  419.  
  420. #define pir_data_tab    16
  421.  
  422. /* pir Flat-file format:
  423. ENTRY           CCHU       #Type Protein
  424. 12345678901234567890123456789012345678901234567890123456789012345678901234567890
  425. .........1.........2.........3.........4.........5.........6.........7.........8
  426. all data starts at tab=17 or further
  427.  
  428. ENTRY       blah    << Start entry, index it
  429. TITLE        blah       << Index def line == HEADER line
  430. ACCESSION   blah    << Index acc line
  431. KEYWORDS    blah    << index keywords
  432. SOURCE      blah    << index source
  433. REFERENCE   blah    << Index
  434. SUPERFAMILY blah    << Index
  435.             blah    << Index
  436. ANYOTHERS    jazz    << skipit
  437. any word starting w/ "#", skipit
  438. ///                  << end of entry == entry separator
  439. ENTRY           CCHU       #Type Protein
  440. TITLE           Cytochrome c - Human
  441. DATE            #Sequence 30-Sep-1991 #Text 30-Sep-1991
  442. PLACEMENT          1.0    1.0    1.0    1.0    1.0
  443. SOURCE          Homo sapiens #Common-name man
  444. ACCESSION       A31764\ A05676\ A00001
  445. REFERENCE
  446.    #Authors     Evans M.J., Scarpulla R.C.
  447.    #Journal     Proc. Natl. Acad. Sci. U.S.A. (1988) 85:9625-9629
  448.    #Title       The human somatic cytochrome c gene: two classes of
  449.                   processed pseudogenes demarcate a period of rapid
  450.                   molecular evolution.
  451.    #Reference-number A31764
  452.    #Accession   A31764
  453.    #Molecule-type DNA
  454.    #Residues    1-105 <EVA>
  455.    #Cross-reference GB:M22877
  456. REFERENCE
  457.    #Authors     Matsubara H., Smith E.L.
  458.    #Journal     J. Biol. Chem. (1963) 238:2732-2753
  459.    #Reference-number A05676
  460.    #Accession   A05676
  461.    #Molecule-type protein
  462.    #Residues    2-28;29-46;47-100;101-105 <MATS>
  463. REFERENCE
  464.    #Authors     Matsubara H., Smith E.L.
  465.    #Journal     J. Biol. Chem. (1962) 237:3575-3576
  466.    #Reference-number A00001
  467.    #Comment     66-Leu is found in 10% of the molecules in pooled
  468.                   protein.
  469. GENETIC
  470.    #Introns        57/1
  471. SUPERFAMILY     #Name cytochrome c
  472. KEYWORDS        acetylation\ electron transport\ heme\
  473.                   mitochondrion\ oxidative phosphorylation\
  474.                   polymorphism\ respiratory chain
  475. FEATURE
  476.    2-105                   #Protein cytochrome c (experimental)
  477.                              <MAT>\
  478.    2                       #Modified-site acetylated amino end
  479.                              (experimental)\
  480.    15,18                   #Binding-site heme (covalent)\
  481.    19,81                   #Binding-site heme iron (axial ligands)
  482. SUMMARY       #Molecular-weight 11749  #Length 105  #Checksum  3247
  483. SEQUENCE
  484.                 5        10        15        20        25        30
  485.       1 M G D V E K G K K I F I M K C S Q C H T V E K G G K H K T G
  486.      31 P N L H G L F G R K T G Q A P G Y S Y T A A N K N K G I I W
  487.      61 G E D T L M E Y L E N P K K Y I P G T K M I F V G I K K K E
  488.      91 E R A D L I A Y L K K A T N E
  489. ///
  490.  
  491. *****/
  492.  
  493.  
  494. void pir_filter_for_index(line)
  495. char* line;
  496. {
  497.   /* check whether to index anything in line, 
  498.    * call this from pir_header_function which is called for
  499.    * each line.  
  500.    * Blank out parts of line not for indexing...
  501.    */
  502.   char *c;
  503.   long  i;
  504.   
  505.   if (strlen(line) <= pir_data_tab) {
  506.      for (c=line ; *c>=' '; c++) *c=' ';
  507.      keepindexing= false;  
  508.        }
  509.  
  510. /* drop some ref junk that is not of much indexing interest... */
  511.   else if (substrcmp(line, "   #Reference-number ") 
  512.       || substrcmp(line, "   #Residues ")
  513.       || substrcmp(line, "   #Accession ")
  514.        || substrcmp(line, "   #Residues ")
  515.         || substrcmp(line, "   #Cross-reference ")
  516.        || substrcmp(line, "   #Molecule-type ")
  517.        || substrcmp(line, "   #Journal ") ) {   
  518.      for (c=line ; *c>=' '; c++) *c=' ';
  519.      /* keepindexing is based on last main keyword (ENTRY, REF...) */
  520.        }
  521.  
  522.   else if (substrcmp(line, "   ")) {  
  523.     /* some good & bad continuation lines start like this */
  524.        if (!keepindexing) for (c=line ; *c>=' '; c++) *c=' ';
  525.      }
  526.          
  527.   else if ( 
  528.           substrcmp(line, "ENTRY           ") 
  529.       || substrcmp(line, "TITLE           ")
  530.       || substrcmp(line, "SOURCE          ")
  531.       || substrcmp(line, "ACCESSION       ")
  532.       || substrcmp(line, "REFERENCE")  
  533. /* REFERENCE line seems to have no data on line, but it follows (keepindexing) */
  534.       || substrcmp(line, "SUPERFAMILY     ")
  535.       || substrcmp(line, "KEYWORDS        ")
  536.     ){
  537.      for (c=line, i=0; *c>=' ' && i<pir_data_tab; i++, c++) *c=' ';
  538.      keepindexing= true;
  539.      }
  540.  
  541.   else {
  542.      for (c=line ; *c>=' '; c++) *c=' ';
  543.      keepindexing= false;
  544.      }
  545.   
  546.   /* pir -- blank out #words */
  547.   for (c=line; *c != 0; ) {
  548.     if (*c=='#') do { *c++=' '; } while (*c > ' ');
  549.     else c++;    
  550.     }
  551.  
  552. }
  553.  
  554.  
  555.  
  556. boolean pir_separator_function(line)
  557. char *line;
  558. {
  559. /* !! with /// as separator, we get /// at top of entry which will
  560.    screw up seqanal software... */
  561. /*  if ((strlen(line) > 1) && (0==strncmp(line, "///", 2))){
  562.      return(true);
  563.      }  
  564. */
  565.   if ((strlen(line) > pir_data_tab) && substrcmp(line, "ENTRY           ")){
  566.      return(true);
  567.      }
  568.   else{
  569.     return(false);
  570.     }
  571. }
  572.  
  573.  
  574. long pir_date_function(line)
  575. char *line;
  576. { /* later maybe */
  577.     return -1;
  578. }
  579.  
  580.   
  581.  
  582. char *pir_def = bio_header1;
  583. char *pir_accession= bio_header2;
  584.  
  585. void pir_header_function(line)
  586. char *line;
  587. {
  588.   if ((strlen(line) > pir_data_tab) &&
  589.      substrcmp(line, "TITLE           ") &&
  590.      (strlen(pir_def) == 0)){
  591.     strncpy(pir_def, line + pir_data_tab, MAX_HEADER_LEN);
  592.     trim_trailing_newline(pir_def);
  593.     }
  594.     
  595.   else if ((strlen(line) > pir_data_tab) &&
  596.      substrcmp(line, "ACCESSION      ") &&
  597.      (strlen(pir_accession) == 0)){
  598.     /* cut extra acc. numbers from this -- we want only 1st */
  599.     char *cp;
  600.     for (cp=line+pir_data_tab; *cp==' '; cp++) ;
  601.             strncpy(pir_accession, cp, MAX_HEADER_LEN);
  602.     cp= strchr(pir_accession, ' ');
  603.     if (cp!=NULL) *cp=0; /* drop after 1st */
  604.         trim_trailing_newline(pir_accession);
  605.         }
  606.   
  607.   pir_filter_for_index( line);
  608.   
  609. }
  610.  
  611. void pir_finish_header_function(header)
  612. char *header;
  613. {
  614.   if(strlen(pir_def) != 0 && strlen(pir_accession) != 0){
  615.     strncpy(header, pir_accession, MAX_HEADER_LEN);
  616.     s_strncat(header, " ", MAX_HEADER_LEN, MAX_HEADER_LEN);
  617.     s_strncat(header, pir_def, MAX_HEADER_LEN, MAX_HEADER_LEN);
  618.   }
  619.   else if(strlen(pir_def) != 0){
  620.     strncpy(header, pir_def, MAX_HEADER_LEN);
  621.   }
  622.   else if(strlen(pir_accession) != 0){
  623.     strncpy(header, pir_accession, MAX_HEADER_LEN);
  624.   }
  625.   else{
  626.     strcpy(header, "Unknown Entry");
  627.   }
  628.   pir_def[0] = '\0';
  629.   pir_accession[0] = '\0';
  630. }
  631.  
  632.  
  633.  
  634. /* ==========================================
  635.  * ===    EMBL Flat-file Customizations  ===
  636.  * d.g.gilbert, 23Feb92, 
  637.  * ==========================================
  638.  */
  639.  
  640. #define embl_data_tab    5
  641.  
  642. /* EMBL Flat-file format:
  643.  
  644. ID   BAAMYLA    standard; DNA; PRO; 7872 BP.
  645. 1234567890
  646. XX
  647. AC   X62835;
  648. XX
  649. DT   12-NOV-1991 (Rel. 29, Last updated, Version 1)
  650. DT   12-NOV-1991 (Rel. 29, Created)
  651. XX
  652. DE   B.acidocaldarius amy gene for amylase
  653. XX
  654. KW   amy gene; amylase.
  655. XX
  656. OS   Bacillus acidocaldarius
  657. OC   Prokaryota; Bacteria; Firmicutes; Endospore-forming rods and cocci;
  658. OC   Bacillaceae; Bacillus.
  659. XX
  660. RN   [1]
  661. RP   1-7872
  662. RA   Hemila H.O.;
  663. RT   ;
  664. RL   Submitted (22-OCT-1991) on tape to the EMBL Data Library by:
  665. RL   H.O. Hemila, Institute of Biotechnology, Valimotie 7, 00380
  666. RL   Helsinki, FINLAND
  667. XX
  668. RN   [2]
  669. RP   1-7872
  670. RA   Koivula T., Hemilae H.;
  671. RT   ;
  672. RL   Unpublished.
  673. XX
  674. CC   *source: strain=ATCC 27009;
  675. CC   *source: clone_library=lambda gt-10;
  676. XX
  677. FH   Key             Location/Qualifiers
  678. FH
  679. FT   -35_signal      3224..3229
  680. FT   -10_signal      3246..3251
  681. FT   RBS             3288..3294
  682. FT                   /note="amy gene"
  683. FT   CDS             3297..7202
  684. FT                   /gene="amy" /product="amylase"
  685. FT   CDS             7332..>7872
  686. FT                   /product="malE protein-homologue"
  687. XX
  688. SQ   Sequence 7872 BP; 1615 A; 2240 C; 2473 G; 1544 T; 0 other;
  689.      cgttcctcgt gccgtccgaa gcgttcccga cgaatctgcg cggcaccgcc gcgggatctc
  690. //
  691. *****/
  692.  
  693.  
  694.  
  695. void embl_filter_for_index(line)
  696. char* line;
  697. {
  698.   /* check whether to index anything in line, 
  699.    * call this from embl_header_function which is called for
  700.    * each line.  
  701.    * Blank out parts of line not for indexing...
  702.    */
  703.   char *c;
  704.   long  i;
  705.   
  706.   if (strlen(line) <= embl_data_tab) {
  707.      for (c=line; *c>=' '; c++) *c=' ';
  708.        }
  709.      
  710.   else if ( 
  711.           substrcmp(line, "DE   ") 
  712.       || substrcmp(line, "ID   ")
  713.       || substrcmp(line, "AC   ")
  714.       || substrcmp(line, "KW   ")
  715.       || substrcmp(line, "OS   ")
  716.       || substrcmp(line, "OC   ")
  717.       || substrcmp(line, "RA   ")
  718.       || substrcmp(line, "RT   ")
  719.     ){
  720.      for (c=line, i=0; *c>=' ' && i<embl_data_tab; i++, c++) *c=' ';
  721.      }
  722.  
  723.   else {
  724.      for (c=line ; *c>=' '; c++) *c=' ';
  725.      }
  726. }
  727.  
  728.  
  729.  
  730. boolean embl_separator_function(line)
  731. char *line;
  732. {
  733. /* !! with // as separator, we get // at top of entry which will
  734.    screw up seqanal software... */
  735. /*  if ((strlen(line) > 1) && (0==strncmp(line, "//", 2))){
  736.      return(true);
  737.      }  
  738. */
  739.   if ((strlen(line) > embl_data_tab) && substrcmp(line, "ID   ")){
  740.      return(true);
  741.      }
  742.   else{
  743.     return(false);
  744.     }
  745. }
  746.  
  747. /* embl date == 30-SEP-1988 == genbank_date*/
  748.  
  749. long embl_date_function(line)
  750. char *line;
  751. {
  752.   if ((strlen(line) > embl_data_tab) && substrcmp(line, "DT   ")){
  753.     return(genbank_getdate(line+embl_data_tab));
  754.   }
  755.   else 
  756.     return -1;
  757. }
  758.  
  759.   
  760.  
  761. char *embl_def = bio_header1;
  762. char *embl_accession= bio_header2;
  763.  
  764. void embl_header_function(line)
  765. char *line;
  766. {
  767.   if ((strlen(line) > embl_data_tab) &&
  768.      substrcmp(line, "DE   ") &&
  769.      (strlen(embl_def) == 0)){
  770.     strncpy(embl_def, line + embl_data_tab, MAX_HEADER_LEN);
  771.     trim_trailing_newline(embl_def);
  772.     }
  773.     
  774.   else if ((strlen(line) > embl_data_tab) &&
  775.      substrcmp(line, "AC   ") &&
  776.      (strlen(embl_accession) == 0)){
  777.     /* cut extra acc. numbers from this -- we want only 1st */
  778.     char *cp;
  779.     for (cp=line+embl_data_tab; *cp==' '; cp++) ;
  780.       strncpy(embl_accession, cp, MAX_HEADER_LEN);
  781.     cp= strchr(embl_accession, ' ');
  782.     if (cp!=NULL) *cp=0; /* drop after 1st */
  783.         trim_trailing_newline(embl_accession);
  784.     }
  785.   
  786.   embl_filter_for_index( line);
  787.   
  788. }
  789.  
  790. void embl_finish_header_function(header)
  791. char *header;
  792. {
  793.   if(strlen(embl_def) != 0 && strlen(embl_accession) != 0){
  794.     strncpy(header, embl_accession, MAX_HEADER_LEN);
  795.     s_strncat(header, " ", MAX_HEADER_LEN, MAX_HEADER_LEN);
  796.     s_strncat(header, embl_def, MAX_HEADER_LEN, MAX_HEADER_LEN);
  797.   }
  798.   else if(strlen(embl_def) != 0){
  799.     strncpy(header, embl_def, MAX_HEADER_LEN);
  800.   }
  801.   else if(strlen(embl_accession) != 0){
  802.     strncpy(header, embl_accession, MAX_HEADER_LEN);
  803.   }
  804.   else{
  805.     strcpy(header, "Unknown Entry");
  806.   }
  807.   embl_def[0] = '\0';
  808.   embl_accession[0] = '\0';
  809. }
  810.  
  811.  
  812.  
  813. /* ==========================================
  814.  *
  815.  * ===  Prosite Dat & Doc Customizations  ===
  816.  *
  817.  * d.g.gilbert, 18feb92, 
  818.  * gilbertd@bio.indiana.edu
  819.  *
  820.  * ==========================================
  821.  */
  822.  
  823. #define prositedat_data_tab    5
  824.  
  825. /* Prosite DOC format:
  826.  
  827. {END}
  828. {PDOC00002}
  829. {PS00002; GLYCOSAMINOGLYCAN}
  830. {BEGIN}
  831. *************************************
  832. * Glycosaminoglycan attachment site *
  833. *************************************
  834.  
  835. Proteoglycans [1] are complex glycoconjugates consisting of a core  protein to
  836. which a variable number of glycosaminoglycan chains  (such as heparin sulfate,
  837. chondroitin sulfate, etc.) are covalently attached. The glycosaminoglycans are
  838. attached to the core proteins through  a xyloside residue which is  in turn is
  839. linked to  a serine   residue of the protein.    A consensus sequence for  the
  840. attachment  site seems  to exist [2].   However,  it must be noted  that  this
  841. consensus is only based on the sequence of three proteoglycans core proteins.
  842.  
  843. -Consensus pattern: S-G-x-G
  844.                     [S is the attachment site]
  845.  Additional rule: There must be at least  two acidic amino acids from -2 to -4
  846.                   relative to the serine.
  847. -Last update: June 1988 / First entry.
  848.  
  849. [ 1] Hassel J.R., Kimura J.H., Hascall V.C.
  850.      Annu. Rev. Biochem. 55:539-567(1986).
  851. [ 2] Bourdon M.A., Krusius T., Campbell S., Schwarz N.B.
  852.      Proc. Natl. Acad. Sci. U.S.A. 84:3194-3198(1987).
  853. {END}
  854. {PDOC00003}
  855. {PS00003; SULFATATION}
  856. {BEGIN}
  857.  
  858. *****/
  859.  
  860. /* Prosite DAT format:
  861. //
  862. ID   ASN_GLYCOSYLATION; PATTERN.
  863. 1234567890
  864. AC   PS00001;
  865. DT   APR-1990 (CREATED); APR-1990 (DATA UPDATE); APR-1990 (INFO UPDATE).
  866. DE   N-glycosylation site.
  867. PA   N-{P}-[ST]-{P}.
  868. CC   /TAXO-RANGE=??E?V;
  869. CC   /SITE=1,carbohydrate;
  870. CC   /SKIP-FLAG=TRUE;
  871. DO   PDOC00001;
  872. //
  873.  
  874. *****/
  875.  
  876. boolean prositedoc_separator_function(line)
  877. char *line;
  878. {
  879.   if ((strlen(line) > strlen("{END}")) && substrcmp(line, "{END}")){
  880.      return(true);
  881.      }
  882.   else{
  883.     return(false);
  884.     }
  885. }
  886.  
  887.  
  888. char *prositedoc_def = bio_header1;
  889. char *prositedoc_accession= bio_header2;
  890.  
  891. void prositedoc_header_function(line)
  892. char *line;
  893. {
  894.   if ((strlen(line)>2) && (line[0]=='*') && (line[1]==' ') && 
  895.      (strlen(prositedoc_def) == 0)){
  896.     strncpy(prositedoc_def, line + 2, MAX_HEADER_LEN);
  897.     trim_trailing_newline(prositedoc_def);
  898.     }
  899.   else if ((strlen(line)>2) && (line[0]=='{') && 
  900.      (!substrcmp(line, "{END}")) &&
  901.      (strlen(prositedoc_accession) == 0)){
  902.     char *cp;
  903.     strncpy(prositedoc_accession, line+1, MAX_HEADER_LEN);
  904.     cp= strchr(prositedoc_accession, '}');
  905.     if (cp!=NULL) *cp=0;  
  906.     trim_trailing_newline(prositedoc_accession);
  907.     }
  908.   
  909. }
  910.  
  911. void prositedoc_finish_header_function(header)
  912. char *header;
  913. {
  914.   if(strlen(prositedoc_def) != 0 && strlen(prositedoc_accession) != 0){
  915.     strncpy(header, prositedoc_accession, MAX_HEADER_LEN);
  916.     s_strncat(header, " ", MAX_HEADER_LEN, MAX_HEADER_LEN);
  917.     s_strncat(header, prositedoc_def, MAX_HEADER_LEN, MAX_HEADER_LEN);
  918.   }
  919.   else if(strlen(prositedoc_def) != 0){
  920.     strncpy(header, prositedoc_def, MAX_HEADER_LEN);
  921.   }
  922.   else if(strlen(prositedoc_accession) != 0){
  923.     strncpy(header, prositedoc_accession, MAX_HEADER_LEN);
  924.   }
  925.   else{
  926.     strcpy(header, "Unknown Entry");
  927.   }
  928.   prositedoc_def[0] = '\0';
  929.   prositedoc_accession[0] = '\0';
  930. }
  931.  
  932.  
  933. boolean prositedat_separator_function(line)
  934. char *line;
  935. {
  936. /* !! with // as separator, we get // at top of entry which will
  937.    screw up seqanal software... */
  938. /*  if ((strlen(line) > 1) && (0==strncmp(line, "//", 2))){
  939.      return(true);
  940.      }  
  941. */
  942.   if ((strlen(line) > prositedat_data_tab) && substrcmp(line, "ID  ")){
  943.      return(true);
  944.      }
  945.   else{
  946.     return(false);
  947.     }
  948. }
  949.  
  950.  
  951. char *prositedat_def = bio_header1;
  952. char *prositedat_accession= bio_header2;
  953.  
  954. void prositedat_header_function(line)
  955. char *line;
  956. {
  957.   int   i;
  958.  
  959.   if ((strlen(line) > prositedat_data_tab) &&
  960.      substrcmp(line, "DE   ") &&
  961.      (strlen(prositedat_def) == 0)){
  962.     strncpy(prositedat_def, line + prositedat_data_tab, MAX_HEADER_LEN);
  963.     trim_trailing_newline(prositedat_def);
  964.     }
  965.     
  966.   else if ((strlen(line) > prositedat_data_tab) &&
  967.      substrcmp(line, "AC   ") &&
  968.      (strlen(prositedat_accession) == 0)){
  969.     /* cut extra acc. numbers from this -- we want only 1st */
  970.     char *cp;
  971.     for (cp=line+prositedat_data_tab; *cp==' '; cp++) ;
  972.     strncpy(prositedat_accession, cp, MAX_HEADER_LEN);
  973.     cp= strchr(prositedat_accession, ' ');
  974.     if (cp!=NULL) *cp=0; /* drop after 1st */
  975.     trim_trailing_newline(prositedat_accession);
  976.     }
  977.    
  978.   if (strlen(line) > prositedat_data_tab)
  979.     for (i=0; i<prositedat_data_tab; i++) line[i]= ' '; 
  980.   
  981. }
  982.  
  983. void prositedat_finish_header_function(header)
  984. char *header;
  985. {
  986.   if(strlen(prositedat_def) != 0 && strlen(prositedat_accession) != 0){
  987.     strncpy(header, prositedat_accession, MAX_HEADER_LEN);
  988.     s_strncat(header, " ", MAX_HEADER_LEN, MAX_HEADER_LEN);
  989.     s_strncat(header, prositedat_def, MAX_HEADER_LEN, MAX_HEADER_LEN);
  990.   }
  991.   else if(strlen(prositedat_def) != 0){
  992.     strncpy(header, prositedat_def, MAX_HEADER_LEN);
  993.   }
  994.   else if(strlen(prositedat_accession) != 0){
  995.     strncpy(header, prositedat_accession, MAX_HEADER_LEN);
  996.   }
  997.   else{
  998.     strcpy(header, "Unknown Entry");
  999.   }
  1000.   prositedat_def[0] = '\0';
  1001.   prositedat_accession[0] = '\0';
  1002. }
  1003.  
  1004. /* ==================== 
  1005.  *      Bio Journals        
  1006.  * (modified EMBL format) 
  1007.  * dgg
  1008.  * ================== 
  1009.  */
  1010.  
  1011. /******
  1012. //
  1013. RA   Casida L.E. Jr.;
  1014. 123456
  1015. RT   "Protozoan Response to the Addition of Bacterial Predators and Other
  1016. RT   Bacteria to Soil.";
  1017. RL   Appl. Environ. Microbiol. 55:1857-1859(1989).
  1018. //
  1019. RA   Caldwell B.A., Ye C., Griffiths R.P., Moyer C.L., Morita R.Y.;
  1020. RT   "Plasmid Expression and Maintenance during Long-Term Starvation-Survival
  1021. RT   of Bacteria in Well Water.";
  1022. RL   Appl. Environ. Microbiol. 55:1860-1864(1989).
  1023. //
  1024. *******/
  1025.  
  1026. #define biojournal_tab    5
  1027.  
  1028. boolean biojournal_separator_function(line)
  1029. char *line;
  1030. {
  1031.   if ((strlen(line) > 1) && (0==strncmp(line, "//", 2))){
  1032.      return(true);
  1033.      }  
  1034. /*  if ((strlen(line) > biojournal_tab) && substrcmp(line, "RA   ")){
  1035.      return(true);
  1036.      }
  1037. */
  1038.   else{
  1039.     return(false);
  1040.     }
  1041. }
  1042.  
  1043.  
  1044. char *biojournal_title = bio_header1;
  1045. char *biojournal_author= bio_header2;
  1046.  
  1047. void biojournal_header_function(line)
  1048. char *line;
  1049. {
  1050.   int   i;
  1051.  
  1052.   if ((strlen(line) > biojournal_tab) && substrcmp(line, "RT   ") &&
  1053.      (strlen(biojournal_title) == 0)){
  1054.     strncpy(biojournal_title, line + biojournal_tab, MAX_HEADER_LEN);
  1055.     trim_trailing_newline(biojournal_title);
  1056.     }
  1057.     
  1058.   else if ((strlen(line) > biojournal_tab) && substrcmp(line, "RA   ") &&
  1059.      (strlen(biojournal_author) == 0)){
  1060.     char *cp;
  1061.     strncpy(biojournal_author, line+biojournal_tab, MAX_HEADER_LEN);
  1062.     cp= strchr(biojournal_author, ' ');
  1063.     if (cp!=NULL) *cp=0; /* drop after 1st */
  1064.     trim_trailing_newline(biojournal_author);
  1065.     }
  1066.    
  1067.    if (strlen(line) > biojournal_tab)
  1068.     for (i=0; i<biojournal_tab; i++) line[i]= ' '; 
  1069. }
  1070.  
  1071. void biojournal_finish_header_function(header)
  1072. char *header;
  1073. {
  1074.   if(strlen(biojournal_title) != 0 && strlen(biojournal_author) != 0){
  1075.     strncpy(header, biojournal_author, MAX_HEADER_LEN);
  1076.     s_strncat(header, " ", MAX_HEADER_LEN, MAX_HEADER_LEN);
  1077.     s_strncat(header, biojournal_title, MAX_HEADER_LEN, MAX_HEADER_LEN);
  1078.   }
  1079.   else if(strlen(biojournal_title) != 0){
  1080.     strncpy(header, biojournal_title, MAX_HEADER_LEN);
  1081.   }
  1082.   else if(strlen(biojournal_author) != 0){
  1083.     strncpy(header, biojournal_author, MAX_HEADER_LEN);
  1084.   }
  1085.   else{
  1086.     strcpy(header, "Unknown Entry");
  1087.   }
  1088.   biojournal_title[0] = '\0';
  1089.   biojournal_author[0] = '\0';
  1090. }
  1091.  
  1092.  
  1093. /* ==========================================
  1094.  *
  1095.  * ===  Drosophila Redbook Customizations  ===
  1096.  *
  1097.  * d.g.gilbert, 18feb92, 
  1098.  * gilbertd@bio.indiana.edu
  1099.  * ==========================================
  1100.  */
  1101.  
  1102. /*------ example
  1103. #Abnormal:  see A
  1104. #abnormal abdomen:  see a( )
  1105. #Abnormal abdomen:  see A
  1106. # abnormal eye:  see mit15
  1107. #abnormal oocytes:  see abo
  1108. #abnormal tergites:  see abt
  1109. #abnormal wings:  see abw
  1110. #abo:  abnormal oocyte
  1111.  location:  2-44.0 (mapped with respect to J, 2-41).
  1112.  origin:  Naturally occurring allele recovered near Rome,
  1113.    Italy.
  1114.  references:  Sandler, Lindsley, Nicoletti, and Trippa,
  1115.  ...
  1116. ----*/
  1117.  
  1118.  
  1119. boolean redbook_separator_function(line)
  1120. char *line;
  1121. {
  1122.   if(*line=='#'){
  1123.     return(true);
  1124.   }
  1125.   else{
  1126.     return(false);
  1127.   }
  1128. }
  1129.  
  1130. char *redbook_header = bio_header1;
  1131.  
  1132. void redbook_header_function(line)
  1133. char *line;
  1134. {
  1135.   if(redbook_separator_function(line)){
  1136.     strncpy(redbook_header, line + 1, MAX_HEADER_LEN);
  1137.   }
  1138. }
  1139.  
  1140. void redbook_finish_header_function(header)
  1141. char *header;
  1142. {
  1143.   if(strlen(redbook_header) == 0){
  1144.     strncpy(header, "Unknown", MAX_HEADER_LEN);
  1145.   }
  1146.   else{
  1147.     strncpy(header, redbook_header, MAX_HEADER_LEN);
  1148.   }
  1149.   redbook_header[0] = '\0';
  1150. }
  1151.  
  1152.  
  1153. /* ==========================================
  1154.  *
  1155.  * ===  Drosophila flybase Customizations  ===
  1156.  *
  1157.  * d.g.gilbert, 18feb92, 
  1158.  * gilbertd@bio.indiana.edu
  1159.  * ==========================================
  1160.  */
  1161.  
  1162. /*----------------------------------------
  1163. ::::::::::::::
  1164. ABAUTOSY.TEXT
  1165. ::::::::::::::
  1166. LS(2)P6
  1167.      24E-24F        28A-28D             A
  1168. LS(2)P11
  1169.      25E-25F        35D                 A
  1170. ::::::::::::::
  1171. ABDELETE.TEXT
  1172. ::::::::::::::
  1173. Df(1)FM7
  1174.      1A             1B2-1B3             Df   |l(1)1Aa--ac|
  1175. In(1)y3P$+L$-sc8$+R$-
  1176.      1A             1B2-1B3             Df   |y--ac|
  1177. ::::::::::::::
  1178. ABDUPLIC.TEXT
  1179. ::::::::::::::
  1180. In(1)sc8$+L$-EN$+R$-
  1181.      1A             1B2-1B3             Dp   |l(1)1Ac--ac|
  1182. In(1)sc8$+L$-y3P$+R$-
  1183.      1A             1B2-1B3             Dp   |y--ac|
  1184. ::::::::::::::
  1185. ABINSERT.TEXT
  1186. ::::::::::::::
  1187. TE298
  1188.      1E             []                  I
  1189. TE276
  1190.      3A1-3A2        []                  I
  1191. ::::::::::::::
  1192. ABINVERT.TEXT
  1193. ::::::::::::::
  1194. In(1)l-v227
  1195.      1-2            19-20               In
  1196. In(1)y-G
  1197.      1A             1C3-1C4             In   |y--y|;;
  1198. ::::::::::::::
  1199. ABREFS.TEXT
  1200. ::::::::::::::
  1201. 3R3L.3R                                 Novitski, Genetics 98:257
  1202. B$+S$- v$++$- y$++Y$-                   Voelker, Genetics 107:279
  1203. B$+S$-Ybb$+l$-                          Polembo, Molec.Gen.Genet. 195:35
  1204. ::::::::::::::
  1205. ABTRANSL.TEXT
  1206. ::::::::::::::
  1207. T(1;2)gl$++$-
  1208.      1A             21C1                T
  1209. T(1;2)y-v1
  1210.      1A             39                  T    |y--y|;;
  1211. T(1;2)SP55
  1212.      1A             41                  T
  1213. ::::::::::::::
  1214. ABTRANSP.TEXT
  1215. ::::::::::::::
  1216. Tp(3;1)pn36
  1217.      1A             61A                 Tp
  1218. Tp(1;1)Si2
  1219.      1A1-1A8        14D2-14E1           Tp   |r--r|;;
  1220. Tp(1;1)Si2
  1221.      1A1-1A8        18F                 Tp
  1222. ::::::::::::::
  1223. COSMID.TEXT
  1224. ::::::::::::::
  1225. 1A\S\T\U      0          0            0                23E12
  1226. 1A\VS         0          ~50          BH\W             125H10
  1227. 1B\M\U        0          0            0                88B3
  1228. ::::::::::::::
  1229. FUNCTION.TEXT
  1230. ::::::::::::::
  1231. 3-hydroxy-3-methylglutaryl-coenzyme-A-reductase               1.1.1.34  HmG-CoAR
  1232. 6-pyruvoyl-tetrahydropterin-synthase                                     pr
  1233. 14-3-3-protein                                                           D14-3-3
  1234. ::::::::::::::
  1235. LOCI.TEXT
  1236. ::::::::::::::
  1237. 3S18;    3S18-element
  1238.               repetitive-element-3S18
  1239. 4.5SRNA;    4.5SRNA
  1240.           3-[21]     65A
  1241.               RNA-4.5S
  1242. 5HT-R1;    serotonin-receptor-1
  1243.           3-[102]    100A
  1244.               serotonin-receptor
  1245.               transmembrane-protein
  1246.               G-protein-coupled-receptor
  1247. 5HT-R2A;    serotonin-receptor
  1248.           2-[87]     56A-56B
  1249. ::::::::::::::
  1250. LZSYN.TEXT
  1251. ::::::::::::::
  1252.  Acp-g1              AcpG
  1253.  Acr96A              Acr96Aa
  1254.  Aldox-1             Aldox1
  1255. ::::::::::::::
  1256. MAP.TEXT
  1257. ::::::::::::::
  1258. 1-[0]          1A6 ?                            l(1)Ac
  1259. 1-0.0                                           cc
  1260. 1-0.0                                           clv-1
  1261. ::::::::::::::
  1262. REFS.TEXT
  1263. ::::::::::::::
  1264. 4.5SRNA              Steffenson            Genetics 110:s84
  1265. 5HT-R1               Boschert              12th Europ.Dros.Conference
  1266. 5HT-R2A              Boschert              12th Europ.Dros.Conference
  1267. ::::::::::::::
  1268. SYNONYMS.TEXT
  1269. ::::::::::::::
  1270. 1C                                Pk36A
  1271. 1J                                Pk91C
  1272. 2sm$+lab$-                        sm
  1273. 3-2                               Pk45C
  1274. ::::::::::::::
  1275. UID.TEXT
  1276. ::::::::::::::
  1277. 00001;4.5SRNA
  1278. 00002;5SRNA
  1279. 00003;7SLRNA
  1280. 00004;17.6
  1281. -----------------------------*/
  1282.  
  1283. /*  need something like this for some doc formats.... */
  1284.  
  1285.  
  1286.  
  1287. boolean flybase_separator_function(line)
  1288. char *line;
  1289. {
  1290.   if (isgraph(*line)) {
  1291.     return(true);
  1292.   }
  1293.   else{
  1294.     return(false);
  1295.   }
  1296. }
  1297.  
  1298. char *flybase_header = bio_header1;
  1299.  
  1300. void flybase_header_function(line)
  1301. char *line;
  1302. {
  1303.   char *c;
  1304.     int  i;
  1305.     
  1306.   if (flybase_separator_function(line)) {
  1307.       for (c=line, i=0; isgraph(*c) && (i<MAX_HEADER_LEN); )  
  1308.             flybase_header[i++]= *c++; 
  1309.         flybase_header[i]= '\0';
  1310.     }
  1311. }
  1312.  
  1313. void flybase_finish_header_function(header)
  1314. char *header;
  1315. {
  1316.   if(strlen(flybase_header) == 0){
  1317.     strncpy(header, "Unknown", MAX_HEADER_LEN);
  1318.   }
  1319.   else{
  1320.     strncpy(header, flybase_header, MAX_HEADER_LEN);
  1321.   }
  1322.   flybase_header[0] = '\0';
  1323. }
  1324.  
  1325. /* ==========================================
  1326.  * DIN news -- like BIO but "***" separator 
  1327.  * dgg
  1328.  */
  1329.  
  1330. boolean din_hit_head = false;
  1331. char din_header[MAX_HEADER_LEN + 1];
  1332.  
  1333. boolean din_separator_function(line)
  1334. char *line;
  1335. {
  1336.   if ((strlen(line) >= 3) && substrcmp(line, "***")) {
  1337.     return(true);
  1338.   }
  1339.   else{
  1340.     return(false);
  1341.   }
  1342. }
  1343.  
  1344.  
  1345. void din_header_function(line)
  1346. char *line;
  1347. {
  1348.   if(din_hit_head    /* we just hit a seperator previous to this */
  1349.      && strlen(line) > 3        /* line is valid */
  1350.      && isalnum(*line)            /* and is word */
  1351.      && (!din_separator_function(line)) /* we are not on the separator now */
  1352.      && strlen(din_header) == 0){ /* and we have not saved the headline yet */
  1353.     strcpy(din_header, line);
  1354.     waislog(WLOG_MEDIUM, WLOG_INDEX, "storing line: %s", din_header);
  1355.     din_hit_head = false;
  1356.   }
  1357. }
  1358.  
  1359. void din_finish_header_function(header)
  1360. char *header;
  1361. {
  1362.   din_hit_head = true;  /* turn on the flag */
  1363.   if(strlen(din_header) == 0){
  1364.     strcpy(header, "Unknown Title");
  1365.   }
  1366.   else{
  1367.     strcpy(header, din_header);
  1368.   }
  1369.   din_header[0] = '\0';
  1370. }
  1371.  
  1372.  
  1373.  
  1374. #endif /* BIO */
  1375.  
  1376.  
  1377. /* =================================
  1378.  * ===  Groliers Customizations  ===
  1379.  * =================================
  1380.  */
  1381.  
  1382. boolean groliers_separator_function(line)
  1383. char *line;
  1384. {
  1385.   if((strlen(line) > strlen("ARTICLE")) &&
  1386.      substrcmp(line, "ARTICLE")){
  1387.     /* printf("hit %s\n", line); */
  1388.     return(true);
  1389.   }
  1390.   else{
  1391.     return(false);
  1392.   }
  1393. }
  1394.  
  1395. char groliers_header[MAX_HEADER_LEN + 1];
  1396.  
  1397. void groliers_header_function(line)
  1398. char *line;
  1399. {
  1400.   if(groliers_separator_function(line)){
  1401.     s_strncpy(groliers_header, line + strlen("ARTICLE") + 2, MAX_HEADER_LEN);
  1402.   }
  1403. }
  1404.  
  1405. void groliers_finish_header_function(header)
  1406. char *header;
  1407. {
  1408.   if(strlen(groliers_header) == 0){
  1409.     s_strncpy(header, "Unknown Title", MAX_HEADER_LEN);
  1410.   }
  1411.   else{
  1412.     s_strncpy(header, groliers_header, MAX_HEADER_LEN);
  1413.   }
  1414.   groliers_header[0] = '\0';
  1415. }
  1416.  
  1417.  
  1418. /* ==============================
  1419.  * ===  RMail Customizations  ===
  1420.  * ==============================
  1421.  */
  1422.  
  1423. /* this is just a preliminary version. A good version would
  1424.  * produce a headline like gnu emacs RMAIL
  1425.  */
  1426.  
  1427.  
  1428. boolean mail_separator_function(line)
  1429. char *line;
  1430. {
  1431.   /* this should really look for a "<cr><cr>From " rather than "<cr>From " */
  1432.   if((strlen(line) > strlen("From ")) &&
  1433.      substrcmp(line, "From ")){
  1434.     return(true);
  1435.   }
  1436.   else{
  1437.     return(false);
  1438.   }
  1439. }
  1440.  
  1441. boolean rmail_separator_function(line)
  1442. char *line;
  1443. {
  1444.   if(0 == strcmp(line, " \n")){
  1445.     return(true);
  1446.   }
  1447.   else{
  1448.     return(false);
  1449.   }
  1450. }
  1451.  
  1452. /* This one is portable, but might get the wrong answer.
  1453.    I'm open to better code.  - Jonny G
  1454. */
  1455.  
  1456.  
  1457. long my_getdate(line)
  1458. char *line;
  1459. {
  1460.   char date[255], *temp;
  1461.   int day, month, year;
  1462.   char cmonth[25], dow[5], tod[10];
  1463.  
  1464.   strcpy(date, line);
  1465.  
  1466.   temp = date;
  1467.  
  1468.   while(!isdigit(*temp)) temp++;
  1469.  
  1470.   sscanf(temp, "%d %25s %d", &day, cmonth, &year);
  1471.  
  1472.   for(month = 0; months[month] != NULL; month++)
  1473.     if(!strcmp(cmonth, months[month])) break;
  1474.  
  1475.   if (year > 99) year = year % 100;
  1476.  
  1477.   if(day > 0 && 
  1478.      month < 12 &&
  1479.      year > 0) {
  1480.     return (10000 * year + 100 * (month+1) + day);
  1481.   }
  1482.  
  1483.   month = -1; day = -1; year = -1;
  1484.  
  1485.   sscanf(temp, "%d/%d/%d", &month, &day, &year);
  1486.  
  1487.   if (year > 99) year = year % 100;
  1488.  
  1489.   if(day > 0 && 
  1490.      month < 12 &&
  1491.      year > 0) {
  1492.     return (10000 * year + 100 * (month+1) + day);
  1493.   }
  1494.  
  1495.   month = -1; day = -1; year = -1;
  1496.  
  1497.   sscanf(temp, "%d/%d/%d", &year, &month, &day);
  1498.  
  1499.   if (year > 99) year = year % 100;
  1500.  
  1501.   if(day > 0 && 
  1502.      month < 12 &&
  1503.      year > 0) {
  1504.     return (10000 * year + 100 * (month+1) + day);
  1505.   }
  1506.  
  1507.   temp = date;
  1508.  
  1509.   sscanf(temp, "%5s %25s %d %10s %d", dow, cmonth, &day, tod, &year);
  1510.  
  1511.   for(month = 0; months[month] != NULL; month++)
  1512.     if(!strcmp(cmonth, months[month])) break;
  1513.  
  1514.   if (year > 99) year = year % 100;
  1515.  
  1516.   if(day > 0 && 
  1517.      month < 12 &&
  1518.      year > 0) {
  1519.     return (10000 * year + 100 * (month+1) + day);
  1520.   }
  1521.  
  1522.   return 0;
  1523. }
  1524.  
  1525. long mail_date_function(line)
  1526. char *line;
  1527. {
  1528.   if((strlen(line) > strlen("Date: ")) &&
  1529.      substrcmp(line, "Date: ")){
  1530.     return(my_getdate(line+6));
  1531.   }
  1532.   else if((strlen(line) > strlen("From ")) &&
  1533.       substrcmp(line, "From ")){
  1534.     char *p;
  1535.     p = (char*)index(line+5, ' ');
  1536.     if(p != NULL)
  1537.       return(my_getdate(p+1));
  1538.   }
  1539.   else return -1;
  1540. }
  1541.  
  1542.   
  1543.  
  1544. char mail_subject[MAX_HEADER_LEN + 1];
  1545. char mail_from[MAX_HEADER_LEN + 1];
  1546.  
  1547. void mail_header_function(line)
  1548. char *line;
  1549. {
  1550.   if((strlen(line) > strlen("Subject: ")) &&
  1551.      substrcmp(line, "Subject: ") &&
  1552.      (strlen(mail_subject) == 0)){
  1553.     strcpy(mail_subject, "Re: ");
  1554.     s_strncat(mail_subject, line + strlen("Subject: "), MAX_HEADER_LEN, MAX_HEADER_LEN);
  1555.     trim_trailing_newline(mail_subject);
  1556.   }
  1557.   else if((strlen(line) > strlen("From: ")) &&
  1558.      substrcmp(line, "From: ") &&
  1559.      (strlen(mail_from) == 0)){
  1560.     /* this should find the <foo@bar> field in the from list */
  1561.     s_strncpy(mail_from, line + strlen("From: "), MAX_HEADER_LEN);
  1562.     trim_trailing_newline(mail_from);
  1563.   }
  1564.   
  1565. }
  1566.  
  1567. void mail_finish_header_function(header)
  1568. char *header;
  1569. {
  1570.   if(strlen(mail_subject) != 0 &&
  1571.      strlen(mail_from) != 0){
  1572.     /* trim the from line if needed */
  1573.     if(strlen(mail_from) > 10){
  1574.       mail_from[10] = '\0';
  1575.     }
  1576.     s_strncpy(header, mail_from, MAX_HEADER_LEN);
  1577.     s_strncat(header, " ", MAX_HEADER_LEN, MAX_HEADER_LEN);
  1578.     s_strncat(header, mail_subject, MAX_HEADER_LEN, MAX_HEADER_LEN);
  1579.     /* printf("%s\n", header); */
  1580.   }
  1581.   else if(strlen(mail_subject) != 0){
  1582.     s_strncpy(header, mail_subject, MAX_HEADER_LEN);
  1583.   }
  1584.   else if(strlen(mail_from) != 0){
  1585.     s_strncpy(header, mail_from, MAX_HEADER_LEN);
  1586.   }
  1587.   else{
  1588.     strcpy(header, "Unknown Subject");
  1589.   }
  1590.   mail_from[0] = '\0';
  1591.   mail_subject[0] = '\0';
  1592. }
  1593.  
  1594.  
  1595.  
  1596.  
  1597. boolean mail_or_rmail_separator(line)
  1598. char *line;
  1599. {
  1600.   static boolean blank_line = false;
  1601.  
  1602.   if((strlen(line) > strlen("From ")) &&
  1603.      substrcmp(line, "From ") &&
  1604.      blank_line == true){
  1605.     blank_line = false;
  1606.     return(true);
  1607.   }
  1608.   
  1609.   if(substrcmp(line, "")){
  1610.     blank_line = true;
  1611.     return(true);
  1612.   }    
  1613.   
  1614.   if(!strcmp(line, "\n")){
  1615.       blank_line = true;
  1616.     }
  1617.     else{
  1618.       blank_line = false;
  1619.     }
  1620.  
  1621.   return(false);
  1622. }
  1623.  
  1624.  
  1625. /* ========================================
  1626.  * ===  Mail Digest Customizations     ====
  1627.  * ========================================
  1628.  */
  1629.  
  1630. boolean mail_digest_separator_function(line)
  1631. char *line;
  1632. {
  1633.   if((strlen(line) > strlen("-----------------------------")) &&
  1634.      substrcmp(line, "------------------------------")){
  1635.     return(true);
  1636.   }
  1637.   else{
  1638.     return(false);
  1639.   }
  1640. }
  1641.  
  1642. /* ========================================
  1643.  * ===  Listserv Digest Customizations     ====
  1644.  * ========================================
  1645.  */
  1646.  
  1647. char listserv_from[MAX_HEADER_LEN + 1];
  1648. char listserv_subject[MAX_HEADER_LEN + 1];
  1649.  
  1650. boolean listserv_digest_separator_function(line)
  1651. char *line;
  1652. {
  1653.   if((strlen(line) > strlen("========================================")) &&
  1654.      substrcmp(line,"========================================")){
  1655.     return(true);
  1656.   }
  1657.   else{
  1658.     return(false);
  1659.   }
  1660. }  
  1661.  
  1662. long listserv_date_function(line)
  1663. char *line;
  1664. {
  1665.   if((strlen(line) > strlen("Date: ")) && substrcmp(line, "Date: ")){
  1666.     return(my_getdate(line+6));
  1667.   }
  1668.   else if((strlen(line) > strlen("From: ")) &&
  1669.      substrcmp(line, "From: ") && (strlen(listserv_from) == 0)){
  1670.     /* this should find the <foo@bar> field in the from list */
  1671.     s_strncpy(listserv_from, line + strlen("From:          "), MAX_HEADER_LEN);
  1672.     trim_trailing_newline(listserv_from);
  1673.   }
  1674.   else return -1;
  1675. }
  1676.  
  1677. void listserv_header_function(line)
  1678. char *line;
  1679. {
  1680.   if((strlen(line) > strlen("Subject: ")) &&
  1681.      substrcmp(line, "Subject: ") && (strlen(listserv_subject) == 0)){
  1682.     strcpy(listserv_subject, "Re: ");
  1683.     s_strncat(listserv_subject, line + strlen("Subject:      "), MAX_HEADER_LEN, MAX_HEADER_LEN);
  1684.     trim_trailing_newline(listserv_subject);
  1685.   }
  1686.   else if((strlen(line) > strlen("From: ")) &&
  1687.      substrcmp(line, "From: ") && (strlen(listserv_from) == 0)){
  1688. /*    printf("1: ->%s<-\n",line); */
  1689.     /* this should find the <foo@bar> field in the from list */
  1690.     s_strncpy(listserv_from, line + strlen("From:         "), MAX_HEADER_LEN);
  1691.     trim_trailing_newline(listserv_from);
  1692.     trim_leading_blanks(listserv_from);
  1693. /*    printf("2: ->%s<-\n",listserv_from); */
  1694.   }
  1695.   
  1696. }
  1697.  
  1698. void listserv_finish_header_function(header)
  1699. char *header;
  1700. {
  1701.   if(strlen(listserv_subject) != 0 && strlen(listserv_from) != 0){
  1702.     /* trim the from line if needed */
  1703.     if(strlen(listserv_from) > 15){
  1704.       listserv_from[15] = '\0';
  1705.     }
  1706.     trim_leading_blanks(listserv_from);
  1707.     s_strncpy(header, listserv_from, MAX_HEADER_LEN);
  1708.     s_strncat(header, " ", MAX_HEADER_LEN, MAX_HEADER_LEN);
  1709.     s_strncat(header, listserv_subject, MAX_HEADER_LEN, MAX_HEADER_LEN);
  1710.     /* printf("%s\n", header); */ 
  1711.   }
  1712.   else if(strlen(listserv_subject) != 0){
  1713.     s_strncpy(header, listserv_subject, MAX_HEADER_LEN);
  1714.   }
  1715.   else if(strlen(listserv_from) != 0){
  1716.     s_strncpy(header, listserv_from, MAX_HEADER_LEN);
  1717.   }
  1718.   else{
  1719.     strcpy(header, "Unknown Subject");
  1720.   }
  1721.   listserv_from[0] = '\0';
  1722.   listserv_subject[0] = '\0';
  1723. }
  1724.  
  1725. /* ========================================
  1726.  * ===  Library Catalog Customizations  ===
  1727.  * ========================================
  1728.  */
  1729.  
  1730. #define TITLE_MARKER "Title: "
  1731. #define FIRST_LINE_MARKER "Call No...."
  1732.  
  1733. /* just use the title */
  1734.  
  1735. boolean catalog_separator_function(line)
  1736. char *line;
  1737. {
  1738.   if (strstr(line, FIRST_LINE_MARKER)) {
  1739.     return(true);
  1740.   }
  1741.   else{
  1742.     return(false);
  1743.   }
  1744. }
  1745.  
  1746. char catalog_header[MAX_HEADER_LEN + 1];
  1747.  
  1748. void catalog_header_function(line)
  1749. char *line;
  1750. {
  1751.   char * title_start;
  1752.   if (title_start = strstr(line, TITLE_MARKER))
  1753.     {
  1754.       strncpy(catalog_header, title_start + strlen(TITLE_MARKER), MAX_HEADER_LEN);
  1755.     }
  1756. }
  1757.  
  1758. void catalog_finish_header_function(header)
  1759. char *header;
  1760. {
  1761.   if(strlen(catalog_header) == 0){
  1762.     strcpy(header, "Unknown Title");
  1763.   }
  1764.   else{
  1765.     s_strncpy(header, catalog_header, MAX_HEADER_LEN);
  1766.   }
  1767.   catalog_header[0] = '\0';
  1768. }
  1769.  
  1770.  
  1771.  
  1772. /* ============================
  1773.  * ===  Bio Customizations  ===
  1774.  * ============================
  1775.  */
  1776.  
  1777. /* customizations for a DB of genetic abstracts */
  1778.  
  1779. boolean hit_header = false;
  1780.  
  1781. boolean bio_separator_function(line)
  1782. char *line;
  1783. {
  1784.   if((strlen(line) > strlen(">>>")) &&
  1785.      substrcmp(line, ">>>")){
  1786.     return(true);
  1787.   }
  1788.   else{
  1789.     return(false);
  1790.   }
  1791. }
  1792.  
  1793. char bio_header[MAX_HEADER_LEN + 1];
  1794.  
  1795. void bio_header_function(line)
  1796. char *line;
  1797.  
  1798. {
  1799.   if(hit_header            /* we just hit a seperator previous to this */
  1800.      && (!bio_separator_function(line)) /* we are not on the separator now */
  1801.      && strlen(bio_header) == 0){ /* and we have not saved the headline yet */
  1802.     strcpy(bio_header, line);
  1803.     waislog(WLOG_MEDIUM, WLOG_INDEX, "storing line: %s", bio_header);
  1804.     hit_header = false;
  1805.   }
  1806. }
  1807.  
  1808. void bio_finish_header_function(header)
  1809. char *header;
  1810.  
  1811. {
  1812.   hit_header = true; /* turn on the flag */
  1813.   if(strlen(bio_header) == 0){
  1814.     strcpy(header, "Unknown Title");
  1815.   }
  1816.   else{
  1817.     strcpy(header, bio_header);
  1818.   }
  1819.   bio_header[0] = '\0';
  1820. }
  1821.  
  1822. /* =================================
  1823.  * ===  CMApp   Customizations  ===
  1824.  * =================================
  1825.  */
  1826.  
  1827. boolean cmapp_separator_function(line)
  1828. char *line;
  1829. {
  1830.   if((strlen(line) > strlen("@A")) &&
  1831.      substrcmp(line, "@A")){
  1832.     /* printf("hit %s\n", line); */
  1833.     return(true);
  1834.   }
  1835.   else{
  1836.     return(false);
  1837.   }
  1838. }
  1839.  
  1840. char cmapp_header[MAX_HEADER_LEN + 1];
  1841.  
  1842. void cmapp_header_function(line)
  1843. char *line;
  1844. {
  1845.   if((strlen(line) > strlen("APPLICATION:")) &&
  1846.      substrcmp(line, "APPLICATION:")){
  1847.     /* printf("hit %s\n", line); */
  1848.     s_strncpy(cmapp_header, line + strlen("APPLICATION:"), MAX_HEADER_LEN);
  1849.   }
  1850. }
  1851.  
  1852. void cmapp_finish_header_function(header)
  1853. char *header;
  1854. {
  1855.   if(strlen(cmapp_header) == 0){
  1856.     s_strncpy(header, "Unknown Title", MAX_HEADER_LEN);
  1857.   }
  1858.   else{
  1859.     s_strncpy(header, cmapp_header, MAX_HEADER_LEN);
  1860.   }
  1861.   cmapp_header[0] = '\0';
  1862. }
  1863.  
  1864. /* =================================
  1865.  * ===  Jargon   Customizations  ===
  1866.  * =================================
  1867.  *
  1868.  * GW - updated for Jargon File 2.9.8
  1869.  */
  1870.  
  1871. /*
  1872.  
  1873. Format of an entry:
  1874.  
  1875. [blank line]
  1876. :Title of This entry: first line of text of this entry
  1877.    second line of text of this entry
  1878.    third line of text of this entry
  1879. [blank line]
  1880.  
  1881. Any line which starts with a colon is considered to be the beginning
  1882. of an entry.
  1883.  
  1884. -GW
  1885.  
  1886. */
  1887.  
  1888. static int jargon_seen_entry = 0;
  1889.  
  1890. boolean jargon_separator_function(line)
  1891. register char *line;
  1892. {
  1893.   if(!jargon_seen_entry && line[0] == ':')
  1894.     jargon_seen_entry = 1;
  1895.   return line[0] == ':';
  1896. }
  1897.  
  1898. char jargon_header[MAX_HEADER_LEN + 1];
  1899.  
  1900. void jargon_header_function(line)
  1901. char *line;
  1902. {
  1903.   if(line[0] != ':')
  1904.     return;
  1905.  
  1906.   strncpy(jargon_header,line+1,MAX_HEADER_LEN);
  1907.   jargon_header[MAX_HEADER_LEN] = '\0';
  1908.  
  1909.   if(NULL != (line = strchr(jargon_header,':'))){
  1910.     if(line[1] == ':')
  1911.       line++;
  1912.     line++;
  1913.     line[0] = '\0';
  1914.   }
  1915. }    
  1916.  
  1917. void jargon_finish_header_function(header)
  1918. char *header;
  1919. {
  1920.   if(jargon_seen_entry) {
  1921.     strncpy(header, jargon_header, MAX_HEADER_LEN);
  1922.   }
  1923.   jargon_header[0] = '\0';
  1924. }
  1925.  
  1926.  
  1927. /* =================================
  1928.  * ===  Internet Resource Guide  ===
  1929.  * =================================
  1930.  */
  1931.  
  1932.  
  1933. char irg_header[MAX_HEADER_LEN + 1];
  1934. boolean irg_header_set = FALSE;
  1935.  
  1936. boolean irg_separator_function(line)
  1937. char *line;
  1938. {
  1939.   if(line[0] == 12){  /* control L */
  1940.     irg_header_set = FALSE;
  1941.     return(true);
  1942.   }
  1943.   else
  1944.     return(false);
  1945. }
  1946.  
  1947. void irg_header_function(line)
  1948. char *line;
  1949. {
  1950.   if((irg_header_set == FALSE) &&
  1951.      (line[0] == 32 )){ /* space */
  1952.     s_strncpy(irg_header, line + strspn(line, " "), MAX_HEADER_LEN);
  1953.     irg_header_set = TRUE;
  1954.   }
  1955.   
  1956. }
  1957.  
  1958. void irg_finish_header_function(header)
  1959. char *header;
  1960. {
  1961.   if(strlen(irg_header) == 0){
  1962.     s_strncpy(header, "Unknown Title", MAX_HEADER_LEN);
  1963.   }
  1964.   else{
  1965.     s_strncpy(header, irg_header, MAX_HEADER_LEN);
  1966.   }
  1967.   irg_header[0] = '\0';
  1968.   irg_header_set = FALSE;
  1969. }
  1970.  
  1971. /* ========================
  1972.  * ===  Dash Separator  ===
  1973.  * ========================
  1974.  */
  1975.  
  1976.  
  1977. /*
  1978.  * dash-seperate entries
  1979.  * used in Introduction to Algorithms bug.list, suggestions, etc.
  1980.  * --------------------... at least 20 dashes
  1981.  * header
  1982.  * item
  1983.  *  ..
  1984.  * --------------------... at least 20 dashes
  1985.  */
  1986.  
  1987. boolean dash_separator_function(line)
  1988. char *line;
  1989. {
  1990.   if((strlen(line) > 20) && substrcmp(line,"--------------------")){
  1991.     /* printf("hit %s\n", line); */
  1992.     return(true);
  1993.   }
  1994.   else{
  1995.     return(false);
  1996.   }
  1997. }
  1998.  
  1999. char dash_header[MAX_HEADER_LEN + 1];
  2000.  
  2001. void dash_header_function(line)
  2002. char *line;
  2003. {
  2004.   if(!dash_separator_function(line) &&
  2005.      (strlen(dash_header) < (MAX_HEADER_LEN - 1))){
  2006.     s_strncat(dash_header, line, 
  2007.           MAX_HEADER_LEN, MAX_HEADER_LEN);
  2008.     trim_trailing_newline(dash_header);
  2009.     strncat(dash_header, "  ", MAX_HEADER_LEN);
  2010.   }
  2011. }
  2012.  
  2013. void dash_finish_header_function(header)
  2014. char *header;
  2015. {
  2016.   if (strlen(dash_header) == 0) {
  2017.     strcpy(header, "No Title");
  2018.   }
  2019.   else {
  2020.     s_strncpy(header, dash_header, MAX_HEADER_LEN);
  2021.   }
  2022.   dash_header[0] = '\0';
  2023. }
  2024.  
  2025.  
  2026. /* ============================
  2027.  * ===  one_line Separator  ===
  2028.  * ============================
  2029.  */
  2030.  
  2031. /* this is where each line is a document (good for databases) */
  2032.  
  2033. boolean one_line_hit_header = false;
  2034.  
  2035. boolean one_line_separator_function(line)
  2036. char *line;
  2037. {
  2038.     return(true);
  2039. }
  2040.  
  2041. char one_line_header[MAX_HEADER_LEN + 1];
  2042.  
  2043. void one_line_header_function(line)
  2044. char *line;
  2045. {
  2046.     s_strncpy(one_line_header, line, MAX_HEADER_LEN);
  2047. }
  2048.  
  2049. void one_line_finish_header_function(header)
  2050. char *header;
  2051. {
  2052.   if (strlen(one_line_header) == 0) {
  2053.     strcpy(header, "No Title");
  2054.   }
  2055.   else {
  2056.     s_strncpy(header, one_line_header, MAX_HEADER_LEN);
  2057.   }
  2058.   one_line_header[0] = '\0';
  2059. }
  2060.  
  2061. /* =============================
  2062.  * ===  Paragraph Separator  ===
  2063.  * =============================
  2064.  */
  2065.  
  2066. /* paragraph files - seperated by a blank line.  Next line is the header */
  2067.  
  2068. char para_header[MAX_HEADER_LEN +1];
  2069. static boolean para_start = true;
  2070.  
  2071. boolean para_separator_function(line)
  2072. char *line;
  2073. {
  2074.   if (para_start == true) {
  2075.     para_start = false;
  2076.     return true;
  2077.   }
  2078.   if (strlen(line) < 2)
  2079.     para_start = true;
  2080.   return false;
  2081. }
  2082.  
  2083. void para_header_function(line)
  2084. char *line;
  2085. {
  2086.   if (para_header[0] == 0)
  2087.     s_strncpy(para_header, line, MAX_HEADER_LEN);
  2088. }
  2089.  
  2090. void para_finish_header_function(header)
  2091. char *header;
  2092. {
  2093.   if (strlen(para_header) == 0) {
  2094.     strcpy(header, "No Title");
  2095.   }
  2096.   else {
  2097.     s_strncpy(header, para_header, MAX_HEADER_LEN);
  2098.   }
  2099.   para_header[0] = 0;
  2100. }  
  2101.  
  2102. /* ==========================
  2103.  * ===  Seeker Separator  ===
  2104.  * ==========================
  2105.  */
  2106.  
  2107. boolean seeker_separator_function(line)
  2108. char *line;
  2109. {
  2110.   return(dash_separator_function(line));
  2111. }
  2112.  
  2113. char seeker_header[MAX_HEADER_LEN + 1];
  2114. boolean in_headline = FALSE;
  2115.  
  2116. void seeker_header_function(line)
  2117. char *line;
  2118. {
  2119.   if(strlen(line) > strlen("Headline:") &&
  2120.      substrcmp(line, "Headline:")){
  2121.     in_headline = TRUE;
  2122.     seeker_header[0] = '\0';
  2123.     /* printf("hit headline!\n"); */
  2124.   }
  2125.   else if(in_headline == TRUE &&
  2126.       (strlen(seeker_header) < (MAX_HEADER_LEN - 1))){
  2127.     s_strncat(seeker_header, line, 
  2128.           MAX_HEADER_LEN, MAX_HEADER_LEN);
  2129.     trim_trailing_newline(seeker_header);
  2130.   }
  2131. }
  2132.  
  2133. void seeker_finish_header_function(header)
  2134. char *header;
  2135. {
  2136.   if (strlen(seeker_header) == 0) {
  2137.     strcpy(header, "No Title");
  2138.   }
  2139.   else {
  2140.     s_strncpy(header, seeker_header, MAX_HEADER_LEN);
  2141.   }
  2142.   seeker_header[0] = '\0';
  2143.   in_headline = TRUE;
  2144. }  
  2145.  
  2146. /* ==========================
  2147.  * ===  RLIN Separator  ===
  2148.  * ==========================
  2149.  */
  2150.  
  2151. boolean rlin_separator_function(line)
  2152. char *line;
  2153. {
  2154.   return(dash_separator_function(line));
  2155. }
  2156.  
  2157. char rlin_header[MAX_HEADER_LEN + 1];
  2158. boolean rlin_in_headline = FALSE;
  2159.  
  2160. void rlin_header_function(line)
  2161. char *line;
  2162. {
  2163.   if(rlin_separator_function(line)){
  2164.     rlin_in_headline = TRUE;
  2165.     rlin_header[0] = '\0';
  2166.     /* printf("hit headline!\n"); */
  2167.   }
  2168.   else if(rlin_in_headline == TRUE &&
  2169.       (strlen(rlin_header) < (MAX_HEADER_LEN - 1))){
  2170.     s_strncat(rlin_header, line, 
  2171.           MAX_HEADER_LEN, MAX_HEADER_LEN);
  2172.     trim_trailing_newline(rlin_header);
  2173.   }
  2174. }
  2175.  
  2176. void rlin_finish_header_function(header)
  2177. char *header;
  2178. {
  2179.   if (strlen(rlin_header) == 0) {
  2180.     strcpy(header, "No Title");
  2181.   }
  2182.   else {
  2183.     s_strncpy(header, rlin_header, MAX_HEADER_LEN);
  2184.   }
  2185.   rlin_header[0] = '\0';
  2186.   in_headline = TRUE;
  2187. }  
  2188.  
  2189. /* ========================================
  2190.  * ===  MH_BBoard  Customizations     ====
  2191.  * ========================================
  2192.  */
  2193.  
  2194. /* gcardwel@uci.edu
  2195. MH bboards use a series of control A's to do a blank line.. yuk!
  2196. */
  2197.  
  2198. boolean mh_bboard_separator_function(line)
  2199. char *line;
  2200. {
  2201.   static boolean blank_line = false;
  2202.  
  2203.   if((strlen(line) > strlen("BBoard-ID: ")) &&
  2204.      substrcmp(line, "BBoard-ID: ") &&
  2205.      blank_line == true){
  2206.     blank_line = false;
  2207.     return(true);
  2208.   }
  2209.   
  2210.   if(!strcmp(line, "\001\001\001\001\n")){
  2211.     blank_line = true;
  2212.   }
  2213.   else{
  2214.     blank_line = false;
  2215.   }
  2216.   return (false);
  2217. }
  2218.  
  2219. /*
  2220.  * Customization for files saved from within the 'rn' newsreader.
  2221.  *
  2222.  * These can either be in 'mail' format, or they can be in a similar
  2223.  * format which starts each article with the pseudo-header
  2224.  * 'Article: 42 of comp.sys.foobar'.  Other than that, we treat this
  2225.  * just like 'mail'.
  2226.  *
  2227.  * wollman@uvm.edu, Sun Sep  8 20:12:21 EDT 1991
  2228.  *
  2229.  * dgg added "Path:" fix for netnews/NNTP fetches (!NOT MAIL, NO "From ")
  2230.  * gilbertd@sunflower.bio.indiana.edu
  2231.  */
  2232. boolean rn_separator_function(line)
  2233. char *line;
  2234. {
  2235.   if(!strncmp(line,"From ",5) ||
  2236.     !strncmp(line,"Path: ",6) ||
  2237.     !strncmp(line,"Article ",7) ||
  2238.     !strncmp(line,"Article: ",9))
  2239.     return true;
  2240.   return false;
  2241. }
  2242.  
  2243. /*
  2244.  * Customization for files saved NNTP netnews fetches (!NOT MAIL FORMAT, NO "From ".
  2245.  *
  2246.  * gilbertd@sunflower.bio.indiana.edu
  2247.  */
  2248. boolean netnews_separator_function(line)
  2249. char *line;
  2250. {
  2251.   if(!strncmp(line,"From ",5) ||
  2252.      !strncmp(line,"Article ",7) ||
  2253.      !strncmp(line,"Article: ",9))
  2254.     return true;
  2255.   return false;
  2256. }
  2257.  
  2258. /*
  2259.  * Customizations for GNU Emacs Info files
  2260.  *
  2261.  * When indexing info files, the user must index the files with real text
  2262.  * in them, rather than the file with the tag and indirect tables; otherwise
  2263.  * you'll end up with lots of garbage in your index.
  2264.  *
  2265.  * G. Wollman
  2266.  */
  2267.  
  2268. static int done_headline = 0;
  2269.  
  2270. boolean emacs_info_separator_function(line) /* hate K&R-style definitions */
  2271. char *line;
  2272. {
  2273.   if(line[0] == (char)31) {
  2274.     done_headline = 0;
  2275.     return true;
  2276.   }
  2277.   return false;
  2278. }
  2279.  
  2280. static char emacs_info_headline[MAX_HEADER_LEN+1];
  2281.  
  2282. void emacs_info_header_function(line)
  2283. register char *line;
  2284. {
  2285.   int i;
  2286.  
  2287.   if(done_headline)
  2288.     return;
  2289.  
  2290.   if(strncmp(line,"File: ",6))
  2291.     return;
  2292.  
  2293.   done_headline = 1;
  2294.   line += 6;            /* skip over "File: " */
  2295.  
  2296.   i = 1;
  2297.   emacs_info_headline[0] = '(';
  2298.   while(*line && *line != ',' && (i < MAX_HEADER_LEN-1))
  2299.     emacs_info_headline[i++] = *line++;
  2300.  
  2301.   emacs_info_headline[i++] = ')';
  2302.  
  2303.   line += 9;            /* skip over ", Node: " */
  2304.  
  2305.   /* copy the name of the info node into the headline */
  2306.   while(*line && (i < MAX_HEADER_LEN) && (*line != ','))
  2307.     emacs_info_headline[i++] = *line++;
  2308.  
  2309.   emacs_info_headline[i++] = '\0';
  2310. }
  2311.  
  2312. void emacs_info_finish_header_function(header)
  2313. char *header;
  2314. {
  2315.   strcpy(header,emacs_info_headline);
  2316. }
  2317.  
  2318. /* ========================================
  2319.  * ===    Medline  Customizations      ====
  2320.  * ========================================
  2321.  */
  2322.  
  2323. /* 
  2324.     Francois Schiettecatte
  2325.     with help from:
  2326.     Tom Emmel
  2327.     Karen Phipps
  2328. */
  2329.  
  2330. char medline_header[MAX_HEADER_LEN +1];
  2331. char medline_title[MAX_HEADER_LEN + 1];
  2332. char medline_date[MAX_HEADER_LEN + 1];
  2333. char medline_author[MAX_HEADER_LEN + 1];
  2334.  
  2335. static boolean medline_start = true;
  2336.  
  2337.  
  2338. boolean medline_separator_function(line)
  2339. char *line;
  2340. {
  2341.   if (medline_start == true) {
  2342.     medline_start = false;
  2343.     return true;
  2344.   }
  2345.   if (strlen(line) < 2)
  2346.     medline_start = true;
  2347.   return false;
  2348. }
  2349.  
  2350.  
  2351. void medline_header_function(line)
  2352. char *line;
  2353. {
  2354.  char *ptr;
  2355.  
  2356.  if((strlen(line) > strlen("TI ")) && 
  2357.      (substrcmp(line, "TI "))){    
  2358.     strncpy(medline_title, line + strlen("TI "), MAX_HEADER_LEN);
  2359.   }
  2360.  
  2361.   if((strlen(line) > strlen("SO ")) &&
  2362.      (substrcmp(line, "SO "))){
  2363.    ptr = strchr(line,'1');
  2364.    strncpy(medline_date, ptr, MAX_DATE_LEN);
  2365.   }
  2366.  
  2367.   if((strlen(line) > strlen("AU ")) &&
  2368.      (substrcmp(line, "AU "))){
  2369.     ptr = strtok(line + strlen("AU "),".,");
  2370.     strcpy(medline_author,ptr);
  2371.     strncat(medline_author, "  ", MAX_AUTHOR_LEN); 
  2372.   } 
  2373. }
  2374.  
  2375. void medline_finish_header_function(header)
  2376. char *header;
  2377. {
  2378.   if(strlen(medline_author) > 0 ){
  2379.    strncat(medline_header,medline_author, MAX_HEADER_LEN);
  2380.   }
  2381.   
  2382.   if(strlen(medline_date) > 0 ){
  2383.     strncat(medline_header,"(", MAX_HEADER_LEN);
  2384.     strncat(medline_header,medline_date, MAX_HEADER_LEN);
  2385.     strncat(medline_header,") ", MAX_HEADER_LEN);
  2386.   }
  2387.  
  2388.   if(strlen(medline_title) > 0 ){
  2389.     strncat(medline_header,medline_title, MAX_HEADER_LEN);
  2390.   }
  2391.   
  2392.   if(strlen(medline_header) == 0){
  2393.     strcpy(header, "No Title");
  2394.   }
  2395.   else{
  2396.     strncpy(header, medline_header, MAX_HEADER_LEN);
  2397.   }
  2398.  
  2399.   medline_header[0] = '\0';
  2400.   medline_title[0] = '\0';
  2401.   medline_date[0] = '\0';
  2402.   medline_author[0] = '\0';
  2403. }
  2404.  
  2405.  
  2406.  
  2407.  
  2408. /* ========================================
  2409.  * ===    Refer  Customizations      ====
  2410.  * ========================================
  2411.  */
  2412.  
  2413.  
  2414. /* 
  2415.     Francois Schiettecatte
  2416.     with help from:
  2417.     Tom Emmel
  2418.     Karen Phipps
  2419. */
  2420.  
  2421. char refer_header[MAX_HEADER_LEN +1];
  2422. char refer_title[MAX_HEADER_LEN + 1];
  2423. char refer_date[MAX_HEADER_LEN + 1];
  2424. char refer_author[MAX_HEADER_LEN + 1];
  2425.  
  2426. static boolean refer_start = true;
  2427.  
  2428.  
  2429. boolean refer_separator_function(line)
  2430. char *line;
  2431. {
  2432.   if (refer_start == true) {
  2433.     refer_start = false;
  2434.     return true;
  2435.   }
  2436.   if (strlen(line) < 2)
  2437.     refer_start = true;
  2438.   return false;
  2439. }
  2440.  
  2441.  
  2442. void refer_header_function(line)
  2443. char *line;
  2444. {
  2445.   if((strlen(line) > strlen("%T ")) && 
  2446.      (substrcmp(line, "%T "))){    
  2447.     strncpy(refer_title, line + strlen("%T "), MAX_HEADER_LEN);
  2448.   }
  2449.   else if((strlen(line) > strlen("%B ")) && 
  2450.      (substrcmp(line, "%B ")) && (strlen(refer_title) == 0)){    
  2451.     strncpy(refer_title, line + strlen("%B "), MAX_HEADER_LEN);
  2452.   }
  2453.   
  2454.   if((strlen(line) > strlen("%D ")) &&
  2455.      (substrcmp(line, "%D "))){
  2456.     strncpy(refer_date, line + strlen("%D "), MAX_DATE_LEN);
  2457.   }
  2458.  
  2459.   if((strlen(line) > strlen("%A ")) &&
  2460.      (substrcmp(line, "%A ")) && (strlen(refer_author) == 0)){
  2461.     strncpy(refer_author, line + strlen("%A "), MAX_AUTHOR_LEN);
  2462.     strncat(refer_author, " ", MAX_AUTHOR_LEN);
  2463.   }
  2464.   else if((strlen(line) > strlen("%E ")) &&
  2465.      (substrcmp(line, "%E ")) && (strlen(refer_author) == 0)){
  2466.     strncpy(refer_author, line + strlen("%E "), MAX_AUTHOR_LEN);
  2467.     strncat(refer_author, " ", MAX_AUTHOR_LEN);
  2468.   }
  2469. }
  2470.  
  2471. void refer_finish_header_function(header)
  2472. char *header;
  2473. {
  2474.   if(strlen(refer_author) > 0 ){
  2475.     strncat(refer_header,refer_author, MAX_HEADER_LEN);
  2476.   }
  2477.   
  2478.   if(strlen(refer_date) > 0 ){
  2479.     strncat(refer_header,"(", MAX_HEADER_LEN);
  2480.     strncat(refer_header,refer_date, MAX_HEADER_LEN);
  2481.     strncat(refer_header,") ", MAX_HEADER_LEN);
  2482.   }
  2483.  
  2484.   if(strlen(refer_title) > 0 ){
  2485.     strncat(refer_header,refer_title, MAX_HEADER_LEN);
  2486.   }
  2487.   
  2488.   if(strlen(refer_header) == 0){
  2489.     strncpy(header, "No Title", MAX_HEADER_LEN);
  2490.   }
  2491.   else{
  2492.     strncpy(header, refer_header, MAX_HEADER_LEN);
  2493.   }
  2494.  
  2495.   refer_header[0] = '\0';
  2496.   refer_author[0] = '\0';
  2497.   refer_date[0] = '\0';
  2498.   refer_title[0] = '\0';
  2499. }
  2500.  
  2501.  
  2502.  
  2503.  
  2504. /* ===========================================
  2505.  * ===    First Line  Customizations      ====
  2506.  * ===========================================
  2507.  */
  2508.  
  2509. /* this means the first line of the file is the headline.
  2510.    useful for the lyrics server */
  2511.  
  2512. /* paragraph files - seperated by a blank line.  Next line is the header */
  2513.  
  2514. char first_line_header[MAX_HEADER_LEN +1];
  2515.  
  2516. boolean first_line_separator_function(line)
  2517. char *line;
  2518. {
  2519.   return false;
  2520. }
  2521.  
  2522. void first_line_header_function(line)
  2523. char *line;
  2524. {
  2525.   if (first_line_header[0] == '\0')
  2526.     s_strncpy(first_line_header, line, MAX_HEADER_LEN);
  2527. }
  2528.  
  2529. void first_line_finish_header_function(header)
  2530. char *header;
  2531. {
  2532.   if (strlen(first_line_header) == 0) {
  2533.     strcpy(header, "No Title");
  2534.   }
  2535.   else {
  2536.     s_strncpy(header, first_line_header, MAX_HEADER_LEN);
  2537.   }
  2538.   first_line_header[0] = 0;
  2539. }  
  2540.  
  2541. /* =========================
  2542.  * ===  BIBTEX Separator ===
  2543.  * =========================
  2544.  * S.P.vandeBurgt@research.ptt.nl (Stan)
  2545.  *
  2546.  * BibTeX entries
  2547.  *
  2548.  * @......{
  2549.  * ......
  2550.  * title = header
  2551.  * .......}
  2552.  *
  2553.  */
  2554.  
  2555. static char bibtex_header[MAX_HEADER_LEN + 1];
  2556.  
  2557. boolean bibtex_separator_function(line)
  2558. char *line;
  2559. {
  2560.     char *p = line;
  2561.  
  2562.     while (isspace(*p)) p++; /* skip space */
  2563.     return(*p == '@');
  2564. }
  2565.  
  2566. void bibtex_header_function(line)
  2567. char *line;
  2568. {
  2569.     char *p = line;
  2570.  
  2571.     p = strstr(line, "title");
  2572.     if (p == NULL) p = strstr(line, "Title");
  2573.     if (p == NULL) p = strstr(line, "TITLE");
  2574.     if (p != NULL && (p == line || !isalpha(*(p-1))))
  2575.     {
  2576.       p += 5;
  2577.  
  2578.       while (isspace(*p)) p++; /* skip space */
  2579.       if (*p == '=')          /* should be an '=' now */
  2580.       {
  2581.           p++;
  2582.           /* skip bibtex char's */
  2583.           while (isspace(*p) || *p == '"' || *p == '{') p++;
  2584.           strncpy(bibtex_header, p, MAX_HEADER_LEN);
  2585.           for (p = bibtex_header; *p != '\0'; p++)
  2586.           {
  2587.               /* replace bibtex char's */
  2588.               if (*p == '\n' || *p == '"' || *p == '}' || *p == '{')
  2589.               {
  2590.                   *p = ' ';
  2591.               }
  2592.           }
  2593.       }
  2594.     }
  2595. }
  2596.  
  2597. void bibtex_finish_header_function(header)
  2598. char *header;
  2599. {
  2600.     if (bibtex_header[0] == '\0')
  2601.     {
  2602.       strcpy(header, "Unknown Title");
  2603.     }
  2604.     else{
  2605.       strncpy(header, bibtex_header, MAX_HEADER_LEN);
  2606.     }
  2607.     bibtex_header[0] = '\0';
  2608. }
  2609.  
  2610.  
  2611. /* =========================
  2612.  * ===  NHYP Separator ===
  2613.  * =========================
  2614.  * S.P.vandeBurgt@research.ptt.nl (Stan)
  2615.  * Nhyp entries
  2616.  *
  2617.  * ?:? header
  2618.  * ......
  2619.  * ......
  2620.  *
  2621.  */
  2622.  
  2623. static char nhyp_header[MAX_HEADER_LEN + 1];
  2624.  
  2625. boolean nhyp_separator_function(line)
  2626. char *line;
  2627. {
  2628.     return(strstr(line, "?:?") != NULL);
  2629. }
  2630.  
  2631. void nhyp_header_function(line)
  2632. char *line;
  2633. {
  2634.     char *p = line;
  2635.  
  2636.     p = strstr(line, "?:?");
  2637.     if (p != NULL)
  2638.     {
  2639.       p += 3;
  2640.       while (isspace(*p)) p++; /* skip space */
  2641.       strncpy(nhyp_header, p, MAX_HEADER_LEN);
  2642.       trim_trailing_newline(nhyp_header);
  2643.     }
  2644. }
  2645.  
  2646. void nhyp_finish_header_function(header)
  2647. char *header;
  2648. {
  2649.     if (nhyp_header[0] == '\0')
  2650.     {
  2651.       strcpy(header, "Unknown Title");
  2652.     }
  2653.     else{
  2654.       strncpy(header, nhyp_header, MAX_HEADER_LEN);
  2655.     }
  2656.     nhyp_header[0] = '\0';
  2657. }
  2658.  
  2659.  
  2660.  
  2661. /* ==========================
  2662.  * ===  Objective-C code  ===
  2663.  * ==========================
  2664.  */
  2665.  
  2666.  
  2667. #ifdef NeXT /* only do this if it is on a NeXT */
  2668.  
  2669. /*----------------------- FSA -------------------*/
  2670. #define fsa_max_edges 4
  2671. #define fsa_error_state (-1)
  2672.  
  2673.  
  2674. typedef struct
  2675. {
  2676.     int if_input;
  2677.     int then_goto;
  2678. }
  2679.     fsa_edge;
  2680.  
  2681.  
  2682. /* action (if non-NULL) is excuted before transfer to next state is made */
  2683. /* action takes as arg the int input that will decide the next state */
  2684. typedef struct
  2685. {
  2686.     int default_goto;
  2687.     int n_edges;
  2688.     fsa_edge edges[fsa_max_edges];
  2689.     int (*action)();
  2690. }
  2691.     fsa_vertex;
  2692.  
  2693.  
  2694. int fsa_step(input, state_p, table)
  2695. int input;
  2696. int *state_p;
  2697. fsa_vertex *table;
  2698. {
  2699.     int next_state, e;
  2700.     int (*this_action)();
  2701.  
  2702.  
  2703.     if(*state_p < 0) return(*state_p = fsa_error_state);
  2704.     this_action = table[*state_p].action;
  2705.     if(this_action) this_action(input);
  2706.     for(e=0; e<table[*state_p].n_edges; e++)
  2707.         if(input == table[*state_p].edges[e].if_input)
  2708.         { next_state = table[*state_p].edges[e].then_goto; break; }
  2709.     if(e >= table[*state_p].n_edges) next_state = table[*state_p].default_goto;
  2710.     if(next_state < 0) next_state = fsa_error_state;
  2711.     return(*state_p = next_state);
  2712. }
  2713.  
  2714.  
  2715. /* sends null char as last input, returns final state */
  2716. int fsa_run(s, state_p, table)
  2717. char *s;
  2718. int *state_p;
  2719. fsa_vertex *table;
  2720. {
  2721.     char *p;
  2722.     
  2723.  
  2724.     for(p=s; *p; p++)
  2725.         fsa_step((int) *p, state_p, table);
  2726.     fsa_step(0, state_p, table);
  2727.     return(*state_p);
  2728. }
  2729.  
  2730.  
  2731. /*----------------------- end FSA -------------------*/
  2732.  
  2733.  
  2734. static int wobjc_brace_level = 0;
  2735. static int wobjc_paren_level = 0;
  2736. static int wobjc_strip_state = 0;
  2737. static int wobjc_context = 0;
  2738. static boolean wobjc_separator = false;
  2739. static char wobjc_class[MAX_HEADER_LEN+1];
  2740. static char *wobjc_class_end = 0;
  2741. static char wobjc_header[MAX_HEADER_LEN+1];
  2742. static char *wobjc_header_end = 0;
  2743.  
  2744.  
  2745. #define WOBJC_BLANK " \t\n\r"
  2746. #define WOBJC_WORD "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM_0123456789"
  2747.  
  2748.  
  2749. /* Flag next line as separator, when context fsa says so. */
  2750. static int wobjc_separate(input)
  2751. int input;
  2752. {
  2753.     return(wobjc_separator = true);
  2754. }
  2755.  
  2756.  
  2757. /* FSA to parse objective-C constructs. */
  2758. static fsa_vertex wobjc_context_fsa[] =
  2759. {
  2760.     { 0, 1, {{ '@', 1 }}},            /* look for objc constructs */
  2761.     { 0, 1, {{ 'i', 20 }}},
  2762.     { 3, 1, {{ ' ', 2 }}},                /* look for @imp class */
  2763.     { 4, 1, {{ 'A', 3 }}},
  2764.     { 4, 3, {{ '+', 6 },{ '-', 8 },{ '@', 10 }}},/* in @imp */
  2765.     { 4, 3, {{ '+', 6 },{ '-', 8 },{ '@', 10 }}, wobjc_separate},
  2766.     { 6, 1, {{ '{', 7 }}},            /* look for -method: */
  2767.     { 5, 1, {{ '{', 7 }}},
  2768.     { 8, 1, {{ '{', 9 }}},            /* look for +method: */
  2769.     { 5, 1, {{ '{', 9 }}},
  2770.     { 4, 1, {{ 'e', 11 }}},            /* look for @end of @imp */
  2771.     { 4, 1, {{ 'n', 12 }}},
  2772.     { 4, 1, {{ 'd', 0 }}},
  2773.     { 14, 1, {{ ' ', 13 }}},               /* look for @intf class */
  2774.     { 15, 1, {{ 'A', 14 }}},
  2775.     { 15, 1, {{ '@', 16 }}},            /* in @intf */
  2776.     { 15, 1, {{ 'e', 17 }}},            /* look for @end of @intf */
  2777.     { 15, 1, {{ 'n', 18 }}},
  2778.     { 15, 1, {{ 'd', 19 }}},
  2779.     { 0, 1, {{ '@', 1 }}, wobjc_separate},
  2780.     { 0, 2, {{ 'm', 21 },{ 'n', 33 }}},        /* look for @impl */
  2781.     { 0, 1, {{ 'p', 22 }}},
  2782.     { 0, 1, {{ 'l', 23 }}},
  2783.     { 0, 1, {{ 'e', 24 }}},
  2784.     { 0, 1, {{ 'm', 25 }}},
  2785.     { 0, 1, {{ 'e', 26 }}},
  2786.     { 0, 1, {{ 'n', 27 }}},
  2787.     { 0, 1, {{ 't', 28 }}},
  2788.     { 0, 1, {{ 'a', 29 }}},
  2789.     { 0, 1, {{ 't', 30 }}},
  2790.     { 0, 1, {{ 'i', 31 }}},
  2791.     { 0, 1, {{ 'o', 32 }}},
  2792.     { 0, 1, {{ 'n', 2 }}},
  2793.     { 0, 1, {{ 't', 34 }}},            /* look for @intf */
  2794.     { 0, 1, {{ 'e', 35 }}},
  2795.     { 0, 1, {{ 'r', 36 }}},
  2796.     { 0, 1, {{ 'f', 37 }}},
  2797.     { 0, 1, {{ 'a', 38 }}},
  2798.     { 0, 1, {{ 'c', 39 }}},
  2799.     { 0, 1, {{ 'e', 13 }}}
  2800. };
  2801.  
  2802.  
  2803. /* Action to be used by stripping fsa in non-commented, non-quoted state. */
  2804. /* This runs context fsa. */
  2805. static int wobjc_process_stripped_code(input)
  2806. int input;
  2807. {
  2808.     int context_input;
  2809.     
  2810.  
  2811.     switch(input)
  2812.     {
  2813.         /* Increment brace/paren levels as appropriate. */
  2814.     case '{': wobjc_brace_level++; break;
  2815.     case '}': if(wobjc_brace_level > 0) wobjc_brace_level--; break;
  2816.     case '(': wobjc_paren_level++; break;
  2817.     case ')': if(wobjc_paren_level > 0) wobjc_paren_level--; break;
  2818.     case '\"': break;
  2819.     case '\'': break;
  2820.     case '/': break;
  2821.         
  2822.     default:
  2823.     /* If in correct context and not in brace/paren/comment/quote, */
  2824.     /* then record header info.  */
  2825.         if(wobjc_brace_level==0 && wobjc_paren_level==0)
  2826.     {
  2827.         /* Recording class or instance method.  Ignore multiple blanks. */
  2828.         if(wobjc_context==6 || wobjc_context==8)
  2829.         {
  2830.         if(!wobjc_header_end || wobjc_header_end==wobjc_header)
  2831.         {
  2832.             strcpy(wobjc_header, (wobjc_context==6 ? "+[" : "-["));
  2833.             strcat(wobjc_header, wobjc_class);
  2834.             strcat(wobjc_header, " ");
  2835.             wobjc_header_end = wobjc_header+strlen(wobjc_header);
  2836.         }
  2837.         if((wobjc_header_end - wobjc_header)<(MAX_HEADER_LEN-5)
  2838.             && !(strchr(WOBJC_BLANK, *(wobjc_header_end-1))
  2839.             && strchr(WOBJC_BLANK, input)))
  2840.             { *wobjc_header_end+= input; *wobjc_header_end = 0; }
  2841.         }
  2842.         
  2843.  
  2844.         /* Recording class name for @implementation or @interface. */
  2845.         if(strchr(WOBJC_WORD, input)
  2846.             && (wobjc_context==2 || wobjc_context==3
  2847.             || wobjc_context==13 || wobjc_context==14))
  2848.         {
  2849.             if(wobjc_context==2 || wobjc_context==13 || !wobjc_class_end)
  2850.             wobjc_class_end = wobjc_class;
  2851.             if(wobjc_context==13
  2852.             || (wobjc_context==14 && !wobjc_header_end))
  2853.             wobjc_header_end = wobjc_header;
  2854.         if((wobjc_class_end - wobjc_class_end)<(MAX_HEADER_LEN/2))
  2855.             { *wobjc_class_end+= input; *wobjc_class_end = 0; }
  2856.         if((wobjc_context==13 || wobjc_context==14)
  2857.             && (wobjc_header_end-wobjc_header_end)<(MAX_HEADER_LEN/2))
  2858.             { *wobjc_header_end+= input; *wobjc_header_end = 0; }
  2859.         }
  2860.     }
  2861.     
  2862.     /* Since not in comment/quote, run context fsa. */
  2863.     /* Input is modified like this: */
  2864.     /*    Non-zero brace level => '{'. */
  2865.     /*    Else spaces => ' '. */
  2866.     /*    Else if in correct contexts, word letters => 'A'. */
  2867.     context_input = input;
  2868.     if(wobjc_brace_level>0) context_input = '{';
  2869.     else if(strchr(WOBJC_BLANK, input)) context_input = ' ';
  2870.     else if((wobjc_context==3 || wobjc_context==14)
  2871.         && strchr(WOBJC_WORD, input))
  2872.             context_input = 'A';
  2873.     fsa_step(context_input, &wobjc_context, wobjc_context_fsa);
  2874.     break;
  2875.     }
  2876.     return(true);
  2877. }
  2878.  
  2879.  
  2880. /* FSA to strip out comments and quotes. */
  2881. static fsa_vertex wobjc_strip_fsa[] =
  2882. {
  2883.     { 0, 3, {{ '/', 1 },{ '\"', 5 },{ '\'', 7 }}, wobjc_process_stripped_code},
  2884.     { 0, 2, {{ '*', 2 },{ '/', 4 }}},        /* look for comment */
  2885.     { 2, 1, {{ '*', 3 }}},            /* in /* comment */
  2886.     { 2, 2, {{ '/', 0 },{ '*', 3 }}},
  2887.     { 4, 1, {{ '\n', 0 }, { '\0', 0 }}},    /* in // comment */
  2888.     { 5, 2, {{ '\\', 6 },{ '\"', 0 }}},        /* in " quote */
  2889.     { 5, 0, },
  2890.     { 7, 2, {{ '\\', 8 },{ '\'', 0 }}},        /* in ' quote */
  2891.     { 7, 0, }
  2892. };
  2893.  
  2894.  
  2895. boolean wobjc_separator_function(line)
  2896. char *line;
  2897. {
  2898.     if(wobjc_separator) { wobjc_separator = false; return true; }
  2899.     else return false;
  2900. }
  2901.  
  2902.  
  2903. void wobjc_header_function(line)
  2904. char *line;
  2905. {
  2906.     /* Run stripping fsa, which will run context fsa. */
  2907.     fsa_run(line, &wobjc_strip_state, wobjc_strip_fsa);
  2908.     return;
  2909. }
  2910.  
  2911.  
  2912. void wobjc_finish_header_function(header)
  2913. char *header;
  2914. {
  2915.     char *p;
  2916.     
  2917.  
  2918.     /* Flush terminal blanks and balance opening '[' if any. */
  2919.     for(p=wobjc_header+strlen(wobjc_header);
  2920.         p>wobjc_header && strchr(WOBJC_BLANK, *(p-1)); p--);
  2921.     if(wobjc_header[0]=='+' || wobjc_header[0]=='-') *p+= ']';
  2922.     *p = 0;
  2923.     
  2924.  
  2925.     /* Copy out final header. */
  2926.     strcpy(header, wobjc_header);
  2927.     wobjc_header[0] = 0;
  2928.     wobjc_header_end = wobjc_header;
  2929.     return;
  2930. }
  2931.  
  2932. #endif /* def NeXT */
  2933.  
  2934.  
  2935. /* ==============================
  2936.  * ===  Ziff computer select  ===
  2937.  * ==============================
  2938.  */
  2939.  
  2940. /* these filters index ziff computer select cd-rom files that
  2941.    have been offloaded from the CDROM.  This is for indexing
  2942.    the CACM files that have been explicitly ok'ed by ACM.
  2943.    All other uses would violate the no lan access restrictions
  2944.    of Ziff */
  2945.  
  2946.  
  2947. #define ZIFF_TITLE_MARKER_1 "Title:     "
  2948. #define ZIFF_TITLE_MARKER_2 "Company:   "
  2949. #define ZIFF_FIRST_LINE_MARKER " *****"
  2950.  
  2951. /* just use the title */
  2952.  
  2953. boolean ziff_separator_function(line)
  2954. char *line;
  2955. {
  2956.   if (strstr(line, ZIFF_FIRST_LINE_MARKER)) {
  2957.     return(true);
  2958.   }
  2959.   else{
  2960.     return(false);
  2961.   }
  2962. }
  2963.  
  2964. char ziff_header[MAX_HEADER_LEN + 1];
  2965.  
  2966. void ziff_header_function(line)
  2967. char *line;
  2968. {
  2969.   if (strstr(line, ZIFF_TITLE_MARKER_1) ||
  2970.       strstr(line, ZIFF_TITLE_MARKER_2))
  2971.     {
  2972.       strncpy(ziff_header, line + strlen(ZIFF_TITLE_MARKER_1), 
  2973.           MAX_HEADER_LEN);
  2974.     }
  2975. }
  2976.  
  2977. void ziff_finish_header_function(header)
  2978. char *header;
  2979. {
  2980.   if(strlen(ziff_header) == 0){
  2981.     strcpy(header, "Unknown Title");
  2982.   }
  2983.   else{
  2984.     s_strncpy(header, ziff_header, MAX_HEADER_LEN);
  2985.   }
  2986.   ziff_header[0] = '\0';
  2987. }
  2988.  
  2989. /* special header function for filename only type */
  2990.  
  2991. void filename_finish_header_function(header)
  2992. char* header;
  2993. {
  2994.   char *p = strrchr(current_filename, '/');
  2995.  
  2996.   if (p != NULL) {
  2997.     p++;
  2998.   } else {
  2999.     p = current_filename;
  3000.   }
  3001.  
  3002.   s_strncpy(header, p, MAX_HEADER_LEN);
  3003. }
  3004.  
  3005.  
  3006. #ifdef BIBDB
  3007. /* ============================
  3008.  * ===  Bibdb Separator  ===
  3009.  * ============================
  3010.  */
  3011.  
  3012.  
  3013. /*
  3014.  * formfedd seperate entries
  3015.  * each page is one entry
  3016.  */
  3017.  
  3018. boolean bibdb_hit_header = 0;
  3019.  
  3020. boolean bibdb_separator_function(line)
  3021. char *line;
  3022. {
  3023.   if((strlen(line) < 3) && substrcmp(line," ")){
  3024.     return(true);
  3025.   }
  3026.   else{
  3027.     return(false);
  3028.   }
  3029. }
  3030.  
  3031. char bibdb_header[MAX_HEADER_LEN + 1];
  3032.  
  3033. void bibdb_header_function(line)
  3034. char *line;
  3035. {
  3036.  
  3037.   /*
  3038.   printf("bibdb_header_function: %s %d %d %d\n", line, bibdb_hit_header,
  3039.      bibdb_separator_function(line), strncmp(line, "CK: ", 4)); 
  3040.      */
  3041.   if((bibdb_hit_header<2)
  3042.      && (!bibdb_separator_function(line)))
  3043.     if (!strncmp(line, "CK: ", 4)) {
  3044.       strncpy(bibdb_header, line+4, MAX_HEADER_LEN);
  3045.       bibdb_hit_header++;
  3046.     } else if (!strncmp(line, "TI: ", 4)) {
  3047.       int i;
  3048.       for (i=0;i<21;i++) if (!bibdb_header[i]) bibdb_header[i]=' ';
  3049.       strncpy(&(bibdb_header[20]), line+4, MAX_HEADER_LEN-21);
  3050.       bibdb_hit_header++;
  3051.     }
  3052. }
  3053.  
  3054. void bibdb_finish_header_function(header)
  3055. char *header;
  3056.  
  3057. {
  3058.   bibdb_hit_header = 0; /* turn on the flag */
  3059.   if (strlen(bibdb_header) == 0) {
  3060.     strcpy(header, "No Title");
  3061.   }
  3062.   else {
  3063.     strncpy(header, bibdb_header, MAX_HEADER_LEN);
  3064.   }
  3065.   bibdb_header[0] = '\0';
  3066. }
  3067.  
  3068. long bgetdate(s)
  3069.      char *s;
  3070. {
  3071.   int year, month, day;
  3072.   sscanf(s,"%2d%2d%2d", &year, &month, &day);
  3073.   return (10000 * year + 100 * month + day);
  3074. }
  3075.  
  3076. long bibdb_date_function(line)
  3077. char *line;
  3078. {
  3079.   if((strlen(line) > strlen("ED: ")) &&
  3080.      substrcmp(line, "ED: ")){
  3081.     return(bgetdate(line+4));
  3082.   }
  3083.   else return -1;
  3084. }
  3085.  
  3086. /* ============================
  3087.  * ===  Formfeed Separator  ===
  3088.  * ============================
  3089.  */
  3090.  
  3091.  
  3092. /*
  3093.  * formfeed-seperate entries
  3094.  * each page is one entry
  3095.  */
  3096.  
  3097. boolean formfeed_hit_header = false;
  3098.  
  3099. boolean formfeed_separator_function(line)
  3100. char *line;
  3101. {
  3102.   if((strlen(line) < 3) && substrcmp(line," ")){
  3103.     /* printf("hit %s\n", line); */
  3104.     return(true);
  3105.   }
  3106.   else{
  3107.     return(false);
  3108.   }
  3109. }
  3110.  
  3111. char formfeed_header[MAX_HEADER_LEN + 1];
  3112.  
  3113. void formfeed_header_function(line)
  3114. char *line;
  3115. {
  3116.   if(formfeed_hit_header
  3117.      && (!formfeed_separator_function(line))
  3118.      && strlen(formfeed_header) == 0) {
  3119.     strncpy(formfeed_header, line, MAX_HEADER_LEN);
  3120.     formfeed_hit_header = false;
  3121.   }
  3122. }
  3123.  
  3124. void formfeed_finish_header_function(header)
  3125. char *header;
  3126.  
  3127. {
  3128.   formfeed_hit_header = true; /* turn on the flag */
  3129.   if (strlen(formfeed_header) == 0) {
  3130.     strcpy(header, "No Title");
  3131.   }
  3132.   else {
  3133.     strncpy(header, formfeed_header, MAX_HEADER_LEN);
  3134.   }
  3135.   formfeed_header[0] = '\0';
  3136. }
  3137.  
  3138.  
  3139.  
  3140. /* ==============================
  3141.  * ===  Bibinf Separator ===
  3142.  * ==============================
  3143.  */
  3144.  
  3145. /* each section is one entry */
  3146.  
  3147. int bibinf_hit_header = 0;
  3148.  
  3149. boolean bibinf_separator_function(line)
  3150. char *line;
  3151. {
  3152.   if((strlen(line) < 3) &&  ((*line == '\n')
  3153.      || (*line == '\0'))) {
  3154.     return(true);
  3155.   }
  3156.   else{
  3157.     return(false);
  3158.   }
  3159. }
  3160.  
  3161. #ifdef SIMPLE_BIBINF
  3162. char bibinf_autor[MAX_HEADER_LEN + 1];
  3163. char bibinf_title[MAX_HEADER_LEN + 1];
  3164.  
  3165. void bibinf_header_function(line)
  3166. char *line;
  3167. {
  3168.  
  3169.   if((bibinf_hit_header<2)
  3170.      && (!bibinf_separator_function(line))) {
  3171.     if (!strncmp(line, "Titel: ", 7)) {
  3172.       strncpy(bibinf_title, line+7, MAX_HEADER_LEN);
  3173.       bibinf_hit_header++;
  3174.     } else if (!strncmp(line, "Autor: ", 7)) {
  3175.       strncpy(bibinf_autor, line+7, MAX_HEADER_LEN);
  3176.       bibinf_hit_header++;
  3177.     }
  3178.   }
  3179. }
  3180. void bibinf_finish_header_function(header)
  3181. char *header;
  3182.  
  3183. {
  3184.   if (bibinf_hit_header == 0) {
  3185.     strcpy(header, "No Title");
  3186.   }
  3187.   else {
  3188.     int i;
  3189.     if (strlen(bibinf_autor)>0) {
  3190.       strncpy(header, bibinf_autor, 25);
  3191.     } else {
  3192.       strncpy(header, "No author given",  25);
  3193.     }
  3194.     for (i=strlen(header);i<MAX_HEADER_LEN;header[i++]=' ');
  3195.     if (strlen(bibinf_title)>0) {
  3196.       strncpy(&(header[26]), bibinf_title, MAX_HEADER_LEN-26);
  3197.     } else {
  3198.       strncpy(&(header[26]), "No title given",  MAX_HEADER_LEN-26);
  3199.     }
  3200.   bibinf_hit_header = 0; /* turn on the flag */
  3201.   }
  3202.   bibinf_autor[0] = '\0';
  3203.   bibinf_title[0] = '\0';
  3204. }
  3205.  
  3206. #else
  3207.  
  3208. char bibinf_header[MAX_HEADER_LEN + 1];
  3209. boolean titel = false;
  3210. boolean autor = false;
  3211. boolean hrsgb = false;
  3212.  
  3213. void bibinf_header_function(line)
  3214. char *line;
  3215. {
  3216.   char *word;
  3217.   char bibinf_header_copy[30];
  3218.   int i;
  3219.  
  3220.   if(bibinf_hit_header            /* begin of Autor-line */
  3221.      && (!bibinf_separator_function(line))
  3222.      && (!strncmp(line, "Autor: ", 7))){
  3223.     s_strncpy(bibinf_header_copy, line+7, 26);
  3224.     word = strtok(bibinf_header_copy," ");
  3225.     while(word){
  3226.       if(isalnum(*word)){
  3227.         trim_trailing_newline(word);
  3228.         s_strncat(bibinf_header,word,26,26);
  3229.         s_strncat(bibinf_header," ",26,26);
  3230.       }
  3231.       else if(word[0] == '|'){
  3232.         bibinf_header[strlen(bibinf_header)-1] = '\0';
  3233.         s_strncat(bibinf_header,"; ",26,26);
  3234.       } 
  3235.       word = strtok(NULL," ");
  3236.     }
  3237.     autor = true;
  3238.   }
  3239.   else if(autor && bibinf_hit_header     /* next words of Autor-line */
  3240.           && (!bibinf_separator_function(line))
  3241.           && (strchr(line, ':') == NULL)){
  3242.     s_strncpy(bibinf_header_copy, line, 26);
  3243.     word = strtok(bibinf_header_copy," ");
  3244.     while(word){
  3245.       if(isalnum(*word)){
  3246.         trim_trailing_newline(word);
  3247.         s_strncat(bibinf_header,word,26,26);
  3248.         s_strncat(bibinf_header," ",26,26);
  3249.       }
  3250.       else if(word[0] == '|'){
  3251.         bibinf_header[strlen(bibinf_header)-1] = '\0';
  3252.         s_strncat(bibinf_header,"; ",26,26);
  3253.       } 
  3254.       word = strtok(NULL," ");
  3255.     }
  3256.   }                            /* end of Autor-line */
  3257.                                /* begin of Herausgeber-line */
  3258.   else if(bibinf_hit_header
  3259.           && (!bibinf_separator_function(line))
  3260.           && (!strncmp(line, "Herausgeber: ", strlen("Herausgeber: ")))){
  3261.     s_strncpy(bibinf_header_copy, line+strlen("Herausgeber: "), 26);
  3262.     word = strtok(bibinf_header_copy," ");
  3263.     while(word){
  3264.       if(isalnum(*word)){
  3265.         trim_trailing_newline(word);
  3266.         s_strncat(bibinf_header,word,26,26);
  3267.         s_strncat(bibinf_header," ",26,26);
  3268.       }
  3269.       else if(word[0] == '|'){
  3270.         bibinf_header[strlen(bibinf_header)-1] = '\0';
  3271.         s_strncat(bibinf_header,"; ",26,26);
  3272.       }
  3273.       word = strtok(NULL," ");
  3274.     }
  3275.     hrsgb = true;
  3276.   }
  3277.   else if(hrsgb && bibinf_hit_header      /* next words of Hrsgb-line */
  3278.           && (!bibinf_separator_function(line))
  3279.           && (strchr(line, ':') == NULL)){
  3280.     s_strncpy(bibinf_header_copy, line, 26);
  3281.     word = strtok(bibinf_header_copy," ");
  3282.     while(word){
  3283.       if(isalnum(*word)){
  3284.         trim_trailing_newline(word);
  3285.         s_strncat(bibinf_header,word,26,26);
  3286.         s_strncat(bibinf_header," ",26,26);
  3287.       }
  3288.       else if(word[0] == '|'){
  3289.         bibinf_header[strlen(bibinf_header)-1] = '\0';
  3290.         s_strncat(bibinf_header,"; ",26,26);
  3291.       } 
  3292.       word = strtok(NULL," ");
  3293.     }
  3294.   }                       /* end of Hrsgb-line */
  3295.  
  3296.   else if(bibinf_hit_header          /* begin of Titel-line */
  3297.           && (!bibinf_separator_function(line))
  3298.           && (!strncmp(line, "Titel: ", 7))) {
  3299.     autor = false;
  3300.     hrsgb = false;
  3301.     for(i=strlen(bibinf_header); i < 25; i++)
  3302.       s_strncat(bibinf_header," ",MAX_HEADER_LEN,MAX_HEADER_LEN);
  3303.     s_strncat(bibinf_header,": ",MAX_HEADER_LEN,MAX_HEADER_LEN);
  3304.     s_strncat(bibinf_header, line+7,MAX_HEADER_LEN,MAX_HEADER_LEN);
  3305.     titel = true;
  3306.   }
  3307.   else if                           /* next words of Titel-line */
  3308.     (titel && bibinf_hit_header
  3309.      && (!bibinf_separator_function(line))
  3310.      && (strchr(line, ':') == NULL)){
  3311.       trim_trailing_newline(bibinf_header);
  3312.       for(i=strlen(bibinf_header) - 1; isspace(bibinf_header[i]); i--)
  3313.         bibinf_header[i] = '\0'; 
  3314.       s_strncat(bibinf_header," ",MAX_HEADER_LEN,MAX_HEADER_LEN);
  3315.       s_strncat(bibinf_header,line,MAX_HEADER_LEN,MAX_HEADER_LEN);
  3316.       if(strlen(bibinf_header) == MAX_HEADER_LEN -1)
  3317.         bibinf_header[MAX_HEADER_LEN-2] = '\n'; 
  3318.     }
  3319.   else if
  3320.     (titel && bibinf_hit_header
  3321.      && (!bibinf_separator_function(line))
  3322.      && (strchr(line, ':') != NULL)){
  3323.       titel = false;
  3324.       bibinf_hit_header = false; 
  3325.     }
  3326.   else if (titel){
  3327.     titel = false;
  3328.     bibinf_hit_header = false;     
  3329.   }
  3330. }
  3331.  
  3332. void bibinf_finish_header_function(header)
  3333. char *header;
  3334.  
  3335. {
  3336.   bibinf_hit_header = true; /* turn on the flag */
  3337.   if (strlen(bibinf_header) == 0) {
  3338.     strcpy(header, "No Title");
  3339.   }
  3340.   else {
  3341.     strncpy(header, bibinf_header, MAX_HEADER_LEN);
  3342. /*    s_strncpy(header, bibinf_header,60);
  3343.     if(header[strlen(header)-1] != '\n')
  3344.       strcat(header,"...\n"); */
  3345.   }
  3346.   bibinf_header[0] = '\0';
  3347. }
  3348.  
  3349.  
  3350. #endif /* SIMPLE_BIBINF */
  3351.  
  3352. long binfgetdate(s)
  3353.      char *s;
  3354. {
  3355.   int year, month, day;
  3356.  
  3357.   sscanf(s, "%4d-%2d-%2d", &year, &month, &day);
  3358.   return (10000 * (year - 1900) + 100 * month + day);
  3359. }
  3360.  
  3361. long bibinf_date_function(line)
  3362. char *line;
  3363. {
  3364.   if((strlen(line) > strlen("Erfasst: ")) &&
  3365.      substrcmp(line, "Erfasst: ")){
  3366.     return(binfgetdate(line+9));
  3367.   }
  3368.   else return -1;
  3369. }
  3370.   
  3371.  
  3372. /* ========================================
  3373.  * ===  Irlist Digest Customizations     ====
  3374.  * ========================================
  3375.  */
  3376.  
  3377. boolean irlist_separator_function(line)
  3378. char *line;
  3379. {
  3380.   if (mail_or_rmail_separator(line)) return(true);
  3381.   
  3382.   if((strlen(line) > strlen("*********")) &&
  3383.      substrcmp(line, "**********")){
  3384.     return(true);
  3385.   }
  3386.   else{
  3387.     return(false);
  3388.   }
  3389. }
  3390.  
  3391. void irlist_header_function(line)
  3392. char *line;
  3393. {
  3394.   if((strlen(line) > strlen("Re: ")) &&
  3395.      substrcmp(line, "Re: ") &&
  3396.      (strlen(mail_subject) == 0)){
  3397.     strcpy(mail_subject, "Re: ");
  3398.     s_strncat(mail_subject, line + strlen("Re: "), MAX_HEADER_LEN, MAX_HEADER_LEN);
  3399.     trim_trailing_newline(mail_subject);
  3400.   }
  3401.   else if((strlen(line) > strlen("Fr: ")) &&
  3402.      substrcmp(line, "Fr: ") &&
  3403.      (strlen(mail_from) == 0)){
  3404.     /* this should find the <foo@bar> field in the from list */
  3405.     strncpy(mail_from, line + strlen("Fr: "), MAX_HEADER_LEN);
  3406.     trim_trailing_newline(mail_from);
  3407.   }
  3408.   else mail_header_function(line);
  3409. }
  3410.  
  3411. long irlist_date_function(line)
  3412. char *line;
  3413. {
  3414.   static long last_date = 0;
  3415.   long this_date;
  3416.   
  3417.   if ((this_date = mail_date_function(line)) > 0)
  3418.     return(last_date = this_date);
  3419.   else
  3420.     return(last_date);
  3421. }
  3422.  
  3423. #endif
  3424.  
  3425. #ifdef ESSENCE
  3426. /*
  3427.  *  Essence Summaries
  3428.  *
  3429.  *  Darren R. Hardy (hardy@cs.colorado.edu)
  3430.  *  University of Colorado at Boulder
  3431.  *  October 8, 1992
  3432.  *
  3433.  *  File Format:
  3434.  *
  3435.  *    EssenceSummary: core filename
  3436.  *    filename
  3437.  *    file type
  3438.  *    summarized information until EOF
  3439.  */
  3440.  
  3441. #define ESSENCE_TAG        "EssenceSummary:"
  3442. #define ESSENCE_TAG_LENGTH    15
  3443. #define ESSENCE_BUF        4096
  3444.  
  3445. int essence_track_header = -2;
  3446. char essence_header[ESSENCE_BUF];    /* Complete WAIS Header */
  3447. char essence_corefilename[ESSENCE_BUF];    /* Essence CoreFilename */
  3448. char essence_filename[ESSENCE_BUF];    /* Essence Filename (may be null) */
  3449. char essence_filetype[ESSENCE_BUF];    /* Essence FileType */
  3450.  
  3451. boolean essence_separator_function(line)
  3452. char *line;
  3453. {
  3454. /*  
  3455.     Uncomment this to handle concatenated Essence summaries.
  3456.     This will be useful for handling record-level indexes.
  3457.  
  3458.     if ((strlen(line) > ESSENCE_TAG_LENGTH) && 
  3459.         !strncmp(line, ESSENCE_TAG, ESSENCE_TAG_LENGTH)) {
  3460.         return (true);
  3461.       } 
  3462. */
  3463.         return(false);
  3464. }
  3465.  
  3466. void essence_header_function(line)
  3467. char *line;
  3468. {
  3469.     /*
  3470.         *  If we found the "EssenceSummary:" tag, then read in the
  3471.          *  CoreFilename and initialize variables.
  3472.      */
  3473.     if ((strlen(line) > ESSENCE_TAG_LENGTH) && 
  3474.         !strncmp(line, ESSENCE_TAG, ESSENCE_TAG_LENGTH)) {
  3475.         essence_header[0] = essence_corefilename[0] = 
  3476.         essence_filename[0] = essence_filetype[0] = '\0';
  3477.             s_strncat(essence_corefilename, 
  3478.               line + ESSENCE_TAG_LENGTH + 1, 
  3479.               strlen(line) - (ESSENCE_TAG_LENGTH + 2), 
  3480.               MAX_HEADER_LEN);
  3481.         essence_track_header = 2;
  3482.       } else if (essence_track_header > 0) {
  3483.         /*
  3484.          *  We've read the CoreFilename, now read in the Filename
  3485.          *  and FileType respectively.  
  3486.          */
  3487.             s_strncat(essence_track_header == 2 ? 
  3488.               essence_filename : essence_filetype, 
  3489.               line, strlen(line) - 1, MAX_HEADER_LEN);
  3490.             essence_track_header--;
  3491.       }
  3492. }
  3493.  
  3494. /*
  3495.  *  build the WAIS header using "Filename FileType CoreFilename".  If Filename
  3496.  *  is NULL, then use the last component of CoreFilename as Filename.
  3497.  */
  3498. void essence_finish_header_function(header)
  3499. char *header;
  3500. {
  3501.     char *fnp;    /* Filename pointer */
  3502.  
  3503.     /*
  3504.      *  If we don't know the CoreFilename, then we don't have a Headline.
  3505.      *  Otherwise, build the headline from the CoreFilename, Filename,
  3506.      *  and FileType.  If the Filename is empty, then use the last
  3507.      *  component of the CoreFilename as the Filename.  The headline is
  3508.      *  in the following format:
  3509.      *
  3510.      *    Filename FileType CoreFilename
  3511.      */
  3512.     if (strlen(essence_corefilename) == 0) 
  3513.         s_strncpy(header, "Unknown Title", MAX_HEADER_LEN);
  3514.     else {
  3515.         if (essence_filename[0] == '\n')     /* Empty Filename */
  3516.             /* fnp is last component of CoreFilename */
  3517.             fnp = (fnp = rindex(essence_corefilename,'/')) == NULL ?
  3518.                   &essence_corefilename[0] : fnp + 1;
  3519.         else
  3520.             fnp = &essence_filename[0];    /* We have a Filename */
  3521.  
  3522.         /* Build the header */
  3523.         sprintf(essence_header, "%s %s %s", fnp, essence_filetype, 
  3524.             essence_corefilename);
  3525.         s_strncpy(header, essence_header, MAX_HEADER_LEN);
  3526.     }
  3527.     /* Reset the variables */
  3528.     essence_header[0] = essence_corefilename[0] = essence_filename[0] = 
  3529.     essence_filetype[0] = '\0';
  3530.     essence_track_header = -1;
  3531. }
  3532.  
  3533. #endif /* ESSENCE */
  3534. #ifdef STELAR
  3535.  
  3536. /*=================================
  3537.  *
  3538.  *      STELAR Abstracts
  3539.  *
  3540.  *=================================*/
  3541. char stelar_header[MAX_HEADER_LEN+1];
  3542.  
  3543. boolean stelar_separator_function(line)
  3544.      char *line;
  3545. {
  3546.   return(false);
  3547. }
  3548.  
  3549. void stelar_header_function(line)
  3550.      char *line;
  3551. {
  3552.   char *p;
  3553.  
  3554.   if(stelar_header[0]=='\0' && isspace(line[0]) && strlen(line)>3){
  3555.     p=line;
  3556.     while(isspace(*p)) ++p;
  3557.     strncpy(stelar_header,p,MAX_HEADER_LEN);
  3558.   }
  3559. }
  3560.  
  3561. void stelar_finish_header_function(header)
  3562.      char *header;
  3563. {
  3564.   if(strlen(stelar_header)==0){
  3565.     strcpy(header,"No Title");
  3566.   } else {
  3567.     strncpy(header,stelar_header,MAX_HEADER_LEN);
  3568.   }
  3569.   stelar_header[0]='\0';
  3570. }
  3571.  
  3572. /*=================================
  3573.  *
  3574.  *      AAS Meeting Abstracts
  3575.  *      (using AAS abstract LaTeX macros)
  3576.  *
  3577.  *=================================*/
  3578.  
  3579. #define AASAB_TITLE_MARKER "\\title{"
  3580. #define AASAB_AUTHOR_MARKER "\\author{"
  3581.  
  3582. char aasab_header[MAX_HEADER_LEN+1];
  3583. char aasab_author[MAX_HEADER_LEN+1];
  3584. char aasab_title[MAX_HEADER_LEN+1];
  3585.  
  3586. boolean aasab_separator_function(line)
  3587.      char *line;
  3588. {
  3589.   if ((strlen(line) > strlen("\\documentstyle["))
  3590.       && (substrcmp(line, "aasab"))) {
  3591.     return(true);
  3592.   } else {
  3593.     return(false);
  3594.   }
  3595. }
  3596.  
  3597. void aasab_header_function(line)
  3598.      char *line;
  3599. {
  3600.   char *aas_start;
  3601.   if (aas_start = strstr(line, AASAB_TITLE_MARKER)) {
  3602.     s_strncpy( aasab_title, aas_start+strlen(AASAB_TITLE_MARKER), MAX_HEADER_LEN);
  3603.   } else
  3604.     if (aas_start = strstr(line, AASAB_AUTHOR_MARKER)) {
  3605.       s_strncpy( aasab_author, aas_start+strlen(AASAB_AUTHOR_MARKER), MAX_HEADER_LEN);
  3606.     }
  3607. }
  3608.  
  3609. void aasab_finish_header_function(line)
  3610.      char *line;
  3611. {
  3612.   int nchars;
  3613.   char *p = strrchr(current_filename, '/');
  3614.  
  3615.   if (strlen(aasab_title) == 0) {
  3616.     strcpy( line, "Unknown Title");
  3617.   } else {
  3618.     nchars = 0;
  3619.     while ((nchars < 20) && (aasab_author[nchars] != '}')) {
  3620.       aasab_header[nchars] = aasab_author[nchars];
  3621.       nchars++;
  3622.     }
  3623.     aasab_header[nchars] = '\0';
  3624.  
  3625.     if (p != NULL) {
  3626.       p++;
  3627.     } else {
  3628.       p = current_filename;
  3629.     }
  3630.  
  3631.     s_strncpy( line, p, MAX_HEADER_LEN);
  3632.     s_strncat( line, " ", strlen(" "), MAX_HEADER_LEN);
  3633.     s_strncat( aasab_header, "<> RE: ", strlen("<> RE: "), MAX_HEADER_LEN);
  3634.     s_strncat( aasab_header, aasab_title, MAX_HEADER_LEN, MAX_HEADER_LEN);
  3635.     s_strncat( line, aasab_header, MAX_HEADER_LEN, MAX_HEADER_LEN);
  3636.   }
  3637.   aasab_title[0] = '\0';
  3638. }
  3639.  
  3640. #endif /* STELAR */
  3641.  
  3642. char *URL_prefix=NULL;
  3643. char *URL_trim=NULL;
  3644.  
  3645. #ifdef FIELDS
  3646. /* ============================
  3647.  * ===  Fields Separator  ===
  3648.  * ============================
  3649.  */
  3650.  
  3651.  
  3652. /*
  3653.  * fields-seperate entries
  3654.  * each page is one entry
  3655.  */
  3656.  
  3657. #define MAX_LINE_LENGTH 1000
  3658. extern ltable* Ltable;  /* table for layout */
  3659. boolean fields_hit_header = false;
  3660.  
  3661. boolean fields_separator_function(line)
  3662.      char *line;
  3663. {
  3664.   char tmpline[MAX_LINE_LENGTH];
  3665.   long tmplen;
  3666.  
  3667.   strncpy(tmpline, line, MAX_LINE_LENGTH);
  3668.   tmplen = strlen(tmpline);
  3669.   /*if(tmpline[tmplen - 1] == '\n')
  3670.     tmpline[tmplen - 1] = '\0';*/
  3671.   
  3672.   if (match(tmpline, NULL, NULL, Ltable->field_record_end_pos)) {
  3673.     return(true);
  3674.   }
  3675.   else{
  3676.     return(false);
  3677.   } 
  3678. }
  3679.  
  3680. char fields_header[MAX_HEADER_LEN + 1] = "\n";
  3681. long Lpos = 0;
  3682. long rest_len = 0;
  3683. long number_not_ended_section = 0;
  3684. long gmax_header_len = 0;
  3685.  
  3686. void fields_header_function(line)
  3687.      char *line;
  3688. {
  3689.   long i, tmplen;
  3690.   long begin_pos, end_pos, prev_end_pos;
  3691.   long length;
  3692.   char *start;
  3693.   char tmpline[MAX_LINE_LENGTH];
  3694.   boolean end_pos_matched = false;
  3695.   
  3696.   strncpy(tmpline, line , MAX_LINE_LENGTH);
  3697.   tmplen = strlen(tmpline);
  3698.   /*if(tmpline[tmplen - 1] == '\n')
  3699.     tmpline[tmplen - 1] = '\0';*/
  3700.   
  3701.   if (fields_header[0] == '\n') {
  3702.     bzero(fields_header,MAX_HEADER_LEN+1);
  3703.   }
  3704.  
  3705.   if(number_not_ended_section > 0) {
  3706.     if(match(line,&end_pos,NULL,Ltable->layout[Lpos].end_tag_pos)){
  3707.       if(end_pos > 0) {
  3708.     for(i=0; i<tmplen; i++) {
  3709.       if(isspace(line[i]) || (line[i] == '\t'))
  3710.         /* do nothing */;
  3711.       else {
  3712.         strncpy(tmpline, &line[i], MAX_LINE_LENGTH);
  3713.         break;
  3714.       }
  3715.     }
  3716.     if(rest_len > 0) {
  3717.       length = Ltable->layout[Lpos].len;
  3718.       strncat(&(fields_header[Ltable->layout[Lpos].offset]), tmpline, rest_len);
  3719.       if(length == strlen(&(fields_header[Ltable->layout[Lpos].offset])))
  3720.         number_not_ended_section = 0;
  3721.       else if(length > strlen(&(fields_header[Ltable->layout[Lpos].offset])))
  3722.         rest_len = length - strlen(&(fields_header[Ltable->layout[Lpos].offset]));
  3723.     } else number_not_ended_section = 0;
  3724.       }
  3725.       else number_not_ended_section = 0;
  3726.     }
  3727.     else {
  3728.       for(i=0; i<tmplen; i++) {
  3729.     if(isspace(line[i]) || (line[i] == '\t'))
  3730.       /* do nothing */;
  3731.     else {
  3732.       strncpy(tmpline, &line[i], MAX_LINE_LENGTH);
  3733.       break;
  3734.     }
  3735.       }
  3736.       if(rest_len > 0) {
  3737.     strncat(&(fields_header[Ltable->layout[Lpos].offset]),tmpline,rest_len);
  3738.     length = Ltable->layout[Lpos].len;
  3739.     if(length == strlen(&(fields_header[Ltable->layout[Lpos].offset])))
  3740.       number_not_ended_section = 0;
  3741.     else if(length > strlen(&(fields_header[Ltable->layout[Lpos].offset])))
  3742.       rest_len = length - strlen(&(fields_header[Ltable->layout[Lpos].offset]));
  3743.       } else number_not_ended_section = 0;
  3744.     }
  3745.   }
  3746.   if(gmax_header_len == 0) {
  3747.     for(i=0; i < Ltable->number_of_headlines; i++) {
  3748.       if(gmax_header_len < MAX_HEADER_LEN) {
  3749.     gmax_header_len += Ltable->layout[i].len;
  3750.     if(gmax_header_len > MAX_HEADER_LEN) 
  3751.       Ltable->layout[i].len -= (gmax_header_len - MAX_HEADER_LEN);
  3752.       } 
  3753.       else Ltable->layout[i].len = 0;
  3754.     }
  3755.   }
  3756.     
  3757.   if (!fields_separator_function(line)) {
  3758.     for(i=0; i < Ltable->number_of_headlines; i++) {
  3759.       if(match(line, &begin_pos, &end_pos, Ltable->layout[i].begin_tag_pos)) {
  3760.     prev_end_pos = end_pos;
  3761.     if(match(&line[end_pos],&end_pos,NULL,Ltable->layout[i].end_tag_pos)){
  3762.       end_pos_matched = true;
  3763.       end_pos += prev_end_pos;
  3764.     }
  3765.     length = Ltable->layout[i].len;
  3766.         if(Ltable->layout[i].hline_begin_tag_pos > -1) {
  3767.           if(match(line,NULL,&begin_pos, Ltable->layout[i].hline_begin_tag_pos)) {
  3768.         if(end_pos_matched)
  3769.           tmpline[end_pos] = '\0';
  3770.             start = &tmpline[begin_pos-1];
  3771.       } else {
  3772.         if(end_pos_matched)
  3773.           tmpline[end_pos] = '\0';
  3774.         start = tmpline;
  3775.       }
  3776.         }
  3777.         else {
  3778.       if(end_pos_matched)
  3779.         tmpline[end_pos] = '\0';
  3780.       start = &tmpline[begin_pos];
  3781.     }
  3782.     if((strlen(start) != 0) && (Ltable->layout[i].offset < MAX_HEADER_LEN)) {
  3783.       strncat(&(fields_header[Ltable->layout[i].offset]), start,
  3784.           length - strlen(&(fields_header[Ltable->layout[i].offset])));
  3785.       rest_len = length - strlen(&(fields_header[Ltable->layout[i].offset]));
  3786.       if(rest_len > 0) 
  3787.         if(end_pos_matched == false) {
  3788.           ++number_not_ended_section;
  3789.           Lpos = i;
  3790.         } 
  3791.     }
  3792.       }
  3793.     }
  3794.   }
  3795. }
  3796.  
  3797.  
  3798. #if 0
  3799. void fields_header_function(line)
  3800.      char *line;
  3801. {
  3802.   long i;
  3803.   long begin_pos, end_pos;
  3804.   long length;
  3805.   char *start;
  3806.   if (fields_header[0] == '\n') {
  3807.     bzero(fields_header,MAX_HEADER_LEN+1);
  3808.   }
  3809.   if (!fields_separator_function(line)) {
  3810.     for(i=0; i < Ltable->number_of_headlines; i++) {
  3811.       if(match(line, NULL, &end_pos, Ltable->layout[i].begin_tag_pos)) {
  3812.         if(match(line,NULL,&begin_pos, Ltable->layout[i].hline_begin_tag_pos)){
  3813.           length = Ltable->layout[i].len;
  3814.           start = &line[end_pos];
  3815.           if(match(start,NULL,&end_pos,Ltable->layout[i].end_tag_pos)){
  3816.             if (end_pos < length) {
  3817.               length = end_pos;
  3818.             }
  3819.           } 
  3820.           strncat(&(fields_header[Ltable->layout[i].offset]), start, length);
  3821.         }
  3822.       }
  3823.     }
  3824.   }
  3825. }
  3826. #endif
  3827.  
  3828. void fields_finish_header_function(header)
  3829. char *header;
  3830.  
  3831. {
  3832.   int i;
  3833.  
  3834.   for (i=0;i<=MAX_HEADER_LEN;i++) {
  3835.     if (fields_header[i]) 
  3836.       if (fields_header[i] == '\n')
  3837.         header[i] = ' ';
  3838.       else
  3839.         header[i] = fields_header[i];
  3840.     else
  3841.       header[i] = ' ';
  3842.   }
  3843.  
  3844.   header[MAX_HEADER_LEN]='\0';
  3845.  
  3846.   for (i=MAX_HEADER_LEN-1;i>=0;i--) {
  3847.     if (header[i] == ' ') {
  3848.       header[i] = '\0';
  3849.     } else {
  3850.       break;
  3851.     }
  3852.   }
  3853.   bzero(fields_header,MAX_HEADER_LEN+1);
  3854. }
  3855.  
  3856. long fields_getdate(s)
  3857.      char *s;
  3858. {
  3859.   int year, month, day;
  3860.   char cmonth[25];
  3861.  
  3862.   if(strncmp(Ltable->date_desc, "dmy", 3) == 0) {
  3863.     if(Ltable->month_is_string) {
  3864.       sscanf(s, Ltable->sscanf_arg, &day, cmonth, &year);
  3865.       for(month = 0; months[month] != NULL; month++)
  3866.         if(!strcasecmp(cmonth, months[month])) break;
  3867.     }
  3868.     else sscanf(s, Ltable->sscanf_arg, &day, &month, &year);
  3869.   }
  3870.   else if(strncmp(Ltable->date_desc, "dym", 3) == 0) {
  3871.     if(Ltable->month_is_string) {
  3872.       sscanf(s, Ltable->sscanf_arg, &day, &year, cmonth);
  3873.       for(month = 0; months[month] != NULL; month++)
  3874.         if(!strcasecmp(cmonth, months[month])) break;
  3875.     }
  3876.     else sscanf(s, Ltable->sscanf_arg, &day, &year, &month);
  3877.   }
  3878.   else if(strncmp(Ltable->date_desc, "mdy", 3) == 0) {
  3879.     if(Ltable->month_is_string) {
  3880.       sscanf(s, Ltable->sscanf_arg, cmonth, &day, &year);
  3881.       for(month = 0; months[month] != NULL; month++)
  3882.         if(!strcasecmp(cmonth, months[month])) break;
  3883.     }
  3884.     else sscanf(s, Ltable->sscanf_arg, &month, &day, &year);
  3885.   }
  3886.   else if(strncmp(Ltable->date_desc, "myd", 3) == 0) {
  3887.     if(Ltable->month_is_string) {
  3888.       scanf(s, Ltable->sscanf_arg, cmonth, &year, &day);
  3889.       for(month = 0; months[month] != NULL; month++)
  3890.         if(!strcasecmp(cmonth, months[month])) break;
  3891.     }
  3892.     else sscanf(s, Ltable->sscanf_arg, &month, &year, &day);
  3893.   }
  3894.   else if(strncmp(Ltable->date_desc, "ydm", 3) == 0) {
  3895.     if(Ltable->month_is_string) {
  3896.       sscanf(s, Ltable->sscanf_arg, &year, &day, cmonth);
  3897.       for(month = 0; months[month] != NULL; month++)
  3898.         if(!strcasecmp(cmonth, months[month])) break;
  3899.     }
  3900.     else sscanf(s, Ltable->sscanf_arg, &year, &day, &month);
  3901.   }
  3902.   else {
  3903.     if(Ltable->month_is_string) {
  3904.       sscanf(s, Ltable->sscanf_arg, &year, cmonth, &day);
  3905.       for(month = 0; months[month] != NULL; month++)
  3906.         if(!strcasecmp(cmonth, months[month])) break;
  3907.     }
  3908.     else sscanf(s, Ltable->sscanf_arg, &year, &month, &day);
  3909.   }
  3910.   
  3911.   if (year > 99) year = year % 100;
  3912.   if(day > 0 && month <= 12 && year > 0) {
  3913.     if(Ltable->month_is_string)
  3914.       return (10000 * year + 100 * (month+1) + day);
  3915.     else return (10000 * year + 100 * month + day);
  3916.   }
  3917. }
  3918.  
  3919. long fields_date_function(line)
  3920.      char* line;
  3921. {
  3922.   long begin_pos = 0;
  3923.   char tmpline[MAX_LINE_LENGTH];
  3924.   long tmplen;
  3925.  
  3926.   strncpy(tmpline, line, MAX_LINE_LENGTH);
  3927.   tmplen = strlen(tmpline);
  3928.   /*if(tmpline[tmplen - 1] == '\n')
  3929.     tmpline[tmplen - 1] = '\0';*/
  3930.   
  3931.   if(Ltable->date_tag_pos > -1) {
  3932.     if(match(tmpline, NULL, NULL, Ltable->date_tag_pos) != NULL) {
  3933.       if(Ltable->date_begin_tag_pos > -1) {
  3934.         if(match(tmpline, NULL, &begin_pos, Ltable->date_begin_tag_pos) != NULL) 
  3935.           return(fields_getdate(tmpline + (begin_pos - 1)));
  3936.       }
  3937.       else return(fields_getdate(tmpline));
  3938.     }
  3939.   }
  3940.   return(-1);
  3941. }
  3942.  
  3943. #endif
  3944. /* FIELDS */
  3945.